home *** CD-ROM | disk | FTP | other *** search
/ Electronic Clipper 1995 April / Electronic Clipper 1995-04.iso / pc / pc_users / ideasrc / setup / mplayer / moviewnd.c < prev    next >
Text File  |  1993-04-17  |  148KB  |  3,345 lines

  1.  
  2. // ---------------------------------------------------------------------
  3. //
  4. // MovieWnd.c - Movie Player - QuickTime for Windows
  5. //
  6. //              Version 1.0
  7. //
  8. //              (c) 1988-1992 Apple Computer, Inc. All Rights Reserved.
  9. //
  10. // ---------------------------------------------------------------------
  11.  
  12.  
  13.  
  14. // Includes
  15. // --------
  16.    #include <Windows.H>               // Required by Windows
  17.    #include <commdlg.h>               // Required for PRINTDLG struct
  18.    #include <stdio.h>                 // Required for sprintf routine
  19.    #include <sys\types.h>             // Required for stat.h
  20.    #include <sys\stat.h>              // Required for _stat routine
  21.    #include <math.h>                  // Required for abs()
  22.    #include <string.h>                // Required for memset
  23.  
  24.    #include <qtw.h>                   // Interface to QuickTime
  25.    #include <qtole.h>                 // Interface to qtole dll
  26.  
  27.    #include "common.h"                // Interface to common.c
  28.  
  29.    #include "player.h"                // Interface to other *.c files
  30.    #include "player.hr"               // Defines used in *.rc files
  31.  
  32.  
  33. // Constants
  34. // ---------
  35.    #define GETINFOMOVIEPROP      "Movie"
  36.  
  37.  
  38. // Message-Persistent Data
  39. // -----------------------
  40.    static struct                           // Hungarian notation: g
  41.      {WORD        wMovieCount;             // Used during enumeration for
  42.                                            // duplication checking
  43.       BOOL        bCreating;               //   "    "       "
  44.       HWND        hwndFirstDup;            //   "    "       "
  45.       WORD        wMovieControllerHeight;  // Height of movie controller
  46.       BOOL        bUpdatingInfo;           // Updating info dialog flag
  47.       char        szSelectFormat[30];      // Info dialog selection format string
  48.       char        szNoSelection[20];       // Info dialog "no selection" string
  49.       HICON       hmovieIcon;              // Movie frame icon
  50.       HCURSOR     hcursor;                 // Current cursor. We need to set cursor
  51.                                            // during constrained resizing so class
  52.                                            // cursor must be set to NULL;
  53.       RECT        rcResizeRect;            // Rect used during constrained resizing
  54.       POINT       ptCursorOffset;          // Offset of cursor from edge of wnd rect
  55.       WORD        wSides;                  // Combined width of vertical size borders
  56.       WORD        wTBBorder;               // Combined width of horizontal size borders
  57.       WORD        wTopAndBottom;           // Difference in height between movie and
  58.                                            // movie window. This includes the movie
  59.                                            // controller
  60.       WORD        wSoundOnlyDefWidth;      // Default width of a sound only movie
  61.       WORD        wScaleWidth;             // Scale width used in constrained resize
  62.       WORD        wScaleHeight;            // Scale height used in constrained resize
  63.       BOOL        bFatResizeBorder;        // Flag that causes resize border to be
  64.                                            // drawn 2 pixels thicker
  65.       WNDPROC     lpOldGBProc;             // Original grow box proc
  66.       WNDPROC     lpNewGBProc;             // Subclassed grow box proc
  67.       HWND        hwndMaximizedMovie;      // Handle of maximized movie wnd
  68.       BOOL        bCapturedGrowBox;        // TRUE if the grow box input has
  69.                                            // been captured
  70.      } g;
  71.  
  72. // Macros
  73. // ----------------------
  74. #define ISKEYDOWN( vKey )  (GetKeyState( (int) (vKey) ) < 0 )
  75.  
  76.  
  77. // Exported callback functions
  78. // ----------------------------
  79.    BOOL __export CALLBACK GetInfoDlgProc       (HWND, UINT, WPARAM, LPARAM);
  80.    BOOL __export CALLBACK CheckDupEnumProc     (HWND, LPARAM);
  81.  
  82.    BOOL __export CALLBACK ActionFilter   (MovieController, UINT, LPVOID, LONG);
  83.  
  84.    BOOL __export CALLBACK MovieChildEnumProc   (HWND, LPARAM);
  85.    LONG __export CALLBACK GBSubClassProc       (HWND, UINT, WPARAM, LPARAM);
  86.  
  87. // Internal Function Declarations
  88. // ------------------------------
  89.    static LONG   NEAR PlayerMovieCreate        (HWND, LPARAM );
  90.    static LONG   NEAR PlayerEditCommands       (HWND, WPARAM, WORD);
  91.    static LONG   NEAR PlayerMovieCommands      (HWND, WPARAM, WORD);
  92.    static LONG   NEAR PrintFrame               (HWND, LPPRINTDLG);
  93.    static VOID   NEAR FillMovieInfo            (HWND, NPMOVIEDATA);
  94.    static LONG   NEAR StartTheMovie            (NPMOVIEDATA);
  95.    static LONG   NEAR StopTheMovie             (NPMOVIEDATA);
  96.    static VOID   NEAR UpdateInfoFileName       (NPMOVIEDATA);
  97.    static VOID   NEAR DisplayCurrentSelection  (NPMOVIEDATA);
  98.    static LONG   NEAR ResizeMovieAndWindow     (HWND, BOOL, NPMOVIEDATA, WORD, WORD);
  99.    static LONG   NEAR ResizeMovie              (NPMOVIEDATA, WORD, WORD);
  100.    static LONG   NEAR InitializePopupMenus     (HWND, HMENU, int);
  101.    static LONG   NEAR SetMinMaxInfo            (HWND, NPMOVIEDATA, MINMAXINFO FAR *);
  102.    static VOID   NEAR ActivateTheController    (HWND, NPMOVIEDATA, BOOL);
  103.    static LONG   NEAR PaintTheIcon             (HWND, NPMOVIEDATA);
  104.    static HFONT  NEAR MakeAnArialFont          (HDC, int);
  105.    static VOID   NEAR UpdateGBBoundsRect       (HWND, NPMOVIEDATA);
  106.    static WORD   NEAR InitializeResize         (HWND, NPMOVIEDATA, WORD, POINT);
  107.    static VOID   NEAR DrawTheFrameRect         (LPRECT, BOOL);
  108.    static VOID   NEAR MoveTheMovieResizeRect   (HWND, NPMOVIEDATA,
  109.                                                              WORD, POINT, BOOL);
  110.    static VOID   NEAR GetProportionalDimensions (NPMOVIEDATA, PWORD, PWORD, BOOL);
  111.    static VOID   NEAR AdjustForMinProportionalSize(HWND, NPMOVIEDATA,
  112.                                                          LPWORD, LPWORD, BOOL);
  113.    static BOOL   NEAR IsNormalSize             (LPRECT, NPMOVIEDATA);
  114.    static BOOL   NEAR SubclassTheGrowBox       (HWND, NPMOVIEDATA);
  115.    static BOOL   NEAR InitMaxWndGrowBoxResize  (HWND, POINT);
  116.    static VOID   NEAR MoveTheFrameResizeRect   (HWND, POINT);
  117.    static LONG   NEAR FixUpMovieTiling         (HWND, NPMOVIEDATA, LPWINDOWPOS);
  118.    static VOID   NEAR SetOptionsDefaults       (HWND, NPMOVIEDATA);
  119.    static VOID   NEAR PopulateOptionsStruct    (HWND, NPMOVIEDATA);
  120.  
  121.  
  122. // Function: PlayerMovieWndProc - Player Movie Window Procedure
  123. // --------------------------------------------------------------------
  124. // Parameters: As required by Microsoft Windows
  125. //
  126. // Returns:    Via DefMDIChildProc
  127. // --------------------------------------------------------------------
  128.    LONG __export CALLBACK PlayerMovieWndProc
  129.               (HWND hwndMovie, UINT message, WPARAM wParam, LPARAM lParam)
  130.  
  131.      {NPMOVIEDATA      pMovieData;          // Temp -> to movie data struct
  132.       HMOVIEDATA       hMovieData;          // Temp handle of movie data
  133.       WNDENUMPROC      lpfnEnumMovies;      // -> enumeration proc
  134.       NPMOVIEDATA      pFirstMovieData;     // Temp -> to movie data struct
  135.                                             // used during duplication processing
  136.       WORD             wMovieWidth;         // Movie normal width
  137.       WORD             wMovieHeight;        // Movie normal height
  138.       WORD             wWidth;              // Window width
  139.       WORD             wHeight;             // Window height
  140.       LRESULT          lRetVal;             // Return from DefMDIChildProc
  141.       POINT            ptCursor;            // Cursor position in screen coords.
  142.       LPQTOLE_OLEDATA  lpOleData;           // -> ole data
  143.  
  144.       static WORD      wResizeHitTestCode;  // Equals the NC hit test code when
  145.                                             // resizing with SHIFT or CONTROL
  146.  
  147.  
  148.       pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 );
  149.       if( pMovieData &&
  150.                MCIsPlayerMessage( pMovieData->mcMovieController,
  151.                                      hwndMovie, message, wParam, lParam ))
  152.          return DefMDIChildProc( hwndMovie, message, wParam, lParam );
  153.  
  154.       switch( message )
  155.         {case WM_CREATE:
  156.                 // Load movie frame icon used by all instances
  157.              if( !g.hmovieIcon )
  158.                  g.hmovieIcon = LoadIcon( PlayerQueryResources(),
  159.                                     MAKEINTRESOURCE( PLAYER_MOVIE_ICON ));
  160.              if( !g.hcursor )
  161.                  g.hcursor = LoadCursor( NULL, IDC_ARROW );
  162.  
  163.              return PlayerMovieCreate( hwndMovie, lParam );
  164.  
  165.          case WM_SIZE:
  166.              if( !pMovieData )
  167.                  break;  // break to DefMDIChildProc
  168.  
  169.              wMovieWidth  = LOWORD( lParam );
  170.              if( HIWORD( lParam ) > g.wMovieControllerHeight )
  171.                  wMovieHeight = HIWORD( lParam ) - g.wMovieControllerHeight;
  172.              else
  173.                  wMovieHeight = 0;
  174.  
  175.              if( wParam ) // Minimizing, maximizing, etc
  176.                 {if( wParam == SIZE_MAXIMIZED )
  177.                          // If subclass failed, remove grow box
  178.                     {if( IsZoomed( PlayerQueryFrameWindow()) ||
  179.                                         !pMovieData->bGrowBoxSubclassed )
  180.                        {SetRectEmpty( &pMovieData->rcGrowBox );
  181.                         MCDoAction( pMovieData->mcMovieController,
  182.                             mcActionSetGrowBoxBounds, &pMovieData->rcGrowBox );
  183.                        }
  184.                      else if( pMovieData->wMinMaxEtc == SIZE_MINIMIZED )
  185.                        {// Reset grow box bounds rect
  186.                         UpdateGBBoundsRect( hwndMovie, pMovieData );
  187.                        }
  188.  
  189.                      if( pMovieData->wMinMaxEtc == SIZE_MINIMIZED )
  190.                          StartTheMovie( pMovieData );
  191.  
  192.                      g.hwndMaximizedMovie = hwndMovie;
  193.                      ResizeMovie( pMovieData, wMovieWidth, wMovieHeight);
  194.                     }
  195.                  else if( wParam == SIZE_MINIMIZED )
  196.                     {SetRectEmpty( &pMovieData->rcGrowBox );
  197.                      MCDoAction( pMovieData->mcMovieController,
  198.                             mcActionSetGrowBoxBounds, &pMovieData->rcGrowBox );
  199.  
  200.                      StopTheMovie( pMovieData );
  201.  
  202.                      PaintTheIcon( hwndMovie, pMovieData );
  203.                     }
  204.  
  205.                  pMovieData->wMinMaxEtc = wParam;
  206.                 }
  207.              else if( pMovieData->wMinMaxEtc )  // restoring
  208.                 {  // Reset grow box bounds rect
  209.                  UpdateGBBoundsRect( hwndMovie, pMovieData );
  210.  
  211.                  if( pMovieData->wMinMaxEtc == SIZE_MAXIMIZED )
  212.                     {if( g.hwndMaximizedMovie == hwndMovie )
  213.                          g.hwndMaximizedMovie = NULL;
  214.  
  215.                      ResizeMovie( pMovieData, wMovieWidth, wMovieHeight);
  216.                     }
  217.                  else if( pMovieData->wMinMaxEtc == SIZE_MINIMIZED )
  218.                     {StartTheMovie( pMovieData );
  219.                     }
  220.                  pMovieData->wMinMaxEtc = 0;
  221.                 }
  222.              else if( pMovieData->bDisableSizeMsgProcessing )
  223.                 {   // Already processing create message, menu item or resizing
  224.                     // to aspect ratio or even multiple of pixels according
  225.                     // to key states in the last else under this message
  226.                  pMovieData->bDisableSizeMsgProcessing = FALSE;
  227.                 }
  228.              else
  229.                 {ResizeMovie( pMovieData, wMovieWidth, wMovieHeight);
  230.                 }
  231.  
  232.                 // Need this for movie controller to repaint correctly
  233.                 // when window is small
  234.              if( wResizeHitTestCode ||
  235.                     ( PlayerQueryMDIAction() == PLAYER_WINDOW_TILE ))
  236.                  InvalidateRect( hwndMovie, NULL, FALSE );
  237.  
  238.              break;  // break to DefMDIChildProc
  239.  
  240.          case WM_MOVE:
  241.              if( !pMovieData ||
  242.                    ( pMovieData->wMinMaxEtc == SIZE_MAXIMIZED ) ||
  243.                             ( pMovieData->wMinMaxEtc == SIZE_MINIMIZED ))
  244.                  break;  // break to DefMDIChildProc
  245.  
  246.                 // Need to reset grow box bounds rect after a move because it is
  247.                 // the client rect of the MDI frame window expressed in the client
  248.                 // coordinates of the movie window
  249.              UpdateGBBoundsRect( hwndMovie, pMovieData );
  250.  
  251.              break;  // break to DefMDIChildProc
  252.  
  253.          case WM_WINDOWPOSCHANGING:
  254.              if( pMovieData &&
  255.                       ( PlayerQueryMDIAction() == PLAYER_WINDOW_TILE ))
  256.                 {FixUpMovieTiling( hwndMovie,
  257.                            pMovieData, (LPWINDOWPOS) lParam );
  258.                 }
  259.  
  260.              break;  // break to DefMDIChildProc
  261.  
  262.          case WM_COMMAND:
  263.              switch( wParam )
  264.                 {case PLAYER_EDIT_COPY:         // edit menu popup
  265.                  case PLAYER_EDIT_OPTIONS:
  266.                  case PLAYER_EDIT_CANCELSEL:
  267.                      return PlayerEditCommands
  268.                                   ( hwndMovie, wParam, HIWORD( lParam ));
  269.  
  270.                  case PLAYER_MOVIE_GETINFO:    // movie menu popup
  271.                  case PLAYER_MOVIE_STOPATEND:
  272.                  case PLAYER_MOVIE_LOOP:
  273.                  case PLAYER_MOVIE_BACKANDFORTH:
  274.                  case PLAYER_MOVIE_PLAYSELONLY:
  275.                  case PLAYER_MOVIE_HALFSIZE:
  276.                  case PLAYER_MOVIE_NORMALSIZE:
  277.                  case PLAYER_MOVIE_DOUBLESIZE:
  278.                  case PLAYER_MOVIE_SHOWPOSTER:
  279.                      return PlayerMovieCommands
  280.                                     ( hwndMovie, wParam, HIWORD( lParam ));
  281.  
  282.                  default:
  283.                      break;  // break to DefMDIChildProc
  284.                 }
  285.  
  286.              break;
  287.  
  288.     // WM_USER messages
  289.  
  290.          case WM_PLAYER_PRINTFRAME:
  291.              return PrintFrame( hwndMovie, (LPPRINTDLG) lParam );
  292.  
  293.          case WM_PLAYER_INITPOPUPS:
  294.              return InitializePopupMenus
  295.                      ( hwndMovie, (HMENU) wParam, (int) LOWORD(lParam) );
  296.  
  297.          case WM_PLAYER_ACTIVATEMOVIE:
  298.              if( pMovieData )
  299.                 {SetMovieActive( pMovieData->mMovie, TRUE );
  300.                  SetFocus( hwndMovie );
  301.                 }
  302.  
  303.              return 0L;
  304.  
  305.          case WM_PLAYER_ACTIVATECONTROLLER:
  306.              if( pMovieData && pMovieData->mcMovieController )
  307.                  ActivateTheController( hwndMovie, pMovieData, TRUE );
  308.  
  309.              return 0L;
  310.  
  311.          case WM_PLAYER_PLAYTHEMOVIE: // Send by frame window when it is
  312.                                       // iconized or restored
  313.              if( pMovieData &&
  314.                       ( pMovieData->wMinMaxEtc != SIZE_MINIMIZED ))
  315.                 {if( (BOOL) wParam )
  316.                      StartTheMovie( pMovieData );
  317.                  else
  318.                      StopTheMovie( pMovieData );
  319.                 }
  320.  
  321.              return 0L;
  322.  
  323.          case WM_PLAYER_UPDATEGBBOUNDSRECT:
  324.                 // Frame window sends this message when size changes
  325.              if( !pMovieData ||
  326.                        ( pMovieData->wMinMaxEtc == SIZE_MINIMIZED ))
  327.                  return 0L;
  328.  
  329.              UpdateGBBoundsRect( hwndMovie, pMovieData );
  330.  
  331.              return 0L;
  332.  
  333.     // end WM_USER messages
  334.  
  335.          case WM_NCACTIVATE:
  336.              if( pMovieData && pMovieData->mcMovieController )
  337.                 {   // Activate or deactivate the controller
  338.                  if( (BOOL) wParam )
  339.                     {   // Post message to introduce a delay so that
  340.                         // activation occurs after mouse click.
  341.                         // Activate is called directly if PostMessage fails
  342.                      if( !PostMessage( hwndMovie,
  343.                                   WM_PLAYER_ACTIVATECONTROLLER, TRUE, 0L ))
  344.                          ActivateTheController( hwndMovie, pMovieData, TRUE );
  345.                     }
  346.                  else
  347.                     {ActivateTheController( hwndMovie, pMovieData, FALSE );
  348.                     }
  349.                 }
  350.  
  351.              break;  // break to DefMDIChildProc
  352.  
  353.          case WM_GETMINMAXINFO:
  354.              SetMinMaxInfo( hwndMovie, pMovieData, (MINMAXINFO FAR*) lParam );
  355.              break;  // break to DefMDIChildProc
  356.  
  357.          case WM_QUERYDRAGICON:
  358.              return MAKELONG( g.hmovieIcon, 0 );
  359.  
  360.          case WM_NCHITTEST:
  361.              lRetVal =  DefMDIChildProc
  362.                                 ( hwndMovie, message, wParam, lParam );
  363.              if( pMovieData && pMovieData->bSoundOnly )
  364.                 {switch( LOWORD( lRetVal ))
  365.                     {case HTTOP:
  366.                      case HTBOTTOM:
  367.                          return 0L;
  368.  
  369.                      case HTTOPLEFT:
  370.                      case HTBOTTOMLEFT:
  371.                          return HTLEFT;
  372.  
  373.                      case HTTOPRIGHT:
  374.                      case HTBOTTOMRIGHT:
  375.                          return HTRIGHT;
  376.  
  377.                      default:
  378.                          return lRetVal;
  379.                     }
  380.                 }
  381.              else
  382.                  return lRetVal;
  383.  
  384.          case WM_NCLBUTTONDOWN:     // We must do all border drag resizing
  385.                                     // so we can do the constrained resizing
  386.              if( pMovieData &&
  387.                    ( wResizeHitTestCode = InitializeResize
  388.                       ( hwndMovie, pMovieData, wParam, MAKEPOINT( lParam ))))
  389.                 {SetCapture( hwndMovie );
  390.                  MoveTheMovieResizeRect( hwndMovie, pMovieData,
  391.                            wResizeHitTestCode, MAKEPOINT( lParam ), TRUE );
  392.                  return 0L;
  393.                 }
  394.  
  395.              break;  // break to DefMDIChildProc
  396.  
  397.          case WM_MOUSEMOVE:
  398.              if( wResizeHitTestCode )
  399.                 {ptCursor = MAKEPOINT( lParam );
  400.                  ClientToScreen( hwndMovie, &ptCursor );
  401.                  MoveTheMovieResizeRect( hwndMovie, pMovieData,
  402.                                   wResizeHitTestCode, ptCursor, FALSE );
  403.                 }
  404.              else if( g.bCapturedGrowBox )  // This move is initiated in the
  405.                                             // grow box subclass proc.
  406.                 {ptCursor = MAKEPOINT( lParam );
  407.                  ClientToScreen( hwndMovie, &ptCursor );
  408.                  MoveTheFrameResizeRect( hwndMovie, ptCursor );
  409.                 }
  410.  
  411.              SetCursor( g.hcursor );
  412.              return 0L;
  413.  
  414.          case WM_LBUTTONUP:
  415.              if( wResizeHitTestCode )
  416.                 {DrawTheFrameRect( &g.rcResizeRect, g.bFatResizeBorder );
  417.  
  418.                  ReleaseCapture();
  419.                  DrawTheFrameRect( NULL, FALSE );   // This cleans up
  420.                  ClipCursor( NULL );
  421.                  g.hcursor = LoadCursor( NULL, IDC_ARROW );
  422.  
  423.                  if( !pMovieData->bSoundOnly &&
  424.                        ( ISKEYDOWN( VK_CONTROL ) || ISKEYDOWN( VK_SHIFT )))
  425.                     {wWidth  = g.rcResizeRect.right - g.rcResizeRect.left;
  426.                      wHeight = g.rcResizeRect.bottom - g.rcResizeRect.top;
  427.  
  428.                      AdjustForMinProportionalSize
  429.                              ( hwndMovie, pMovieData,
  430.                                  &wWidth, &wHeight, ISKEYDOWN( VK_CONTROL ));
  431.  
  432.                      g.rcResizeRect.right  = g.rcResizeRect.left + wWidth;
  433.                      g.rcResizeRect.bottom = g.rcResizeRect.top + wHeight;
  434.                     }
  435.  
  436.                  MapWindowPoints( HWND_DESKTOP, PlayerQueryClientWindow(),
  437.                                                (LPPOINT) &g.rcResizeRect, 2 );
  438.  
  439.                  MoveWindow( hwndMovie,
  440.                          g.rcResizeRect.left, g.rcResizeRect.top,
  441.                          g.rcResizeRect.right - g.rcResizeRect.left,
  442.                          g.rcResizeRect.bottom - g.rcResizeRect.top, TRUE );
  443.  
  444.                     // This needs to be after the MoveWindow call
  445.                  wResizeHitTestCode = 0;
  446.                 }
  447.              else if( g.bCapturedGrowBox )  // This move is initiated in the
  448.                                             // grow box subclass proc.
  449.                 {g.bCapturedGrowBox = FALSE;
  450.                  DrawTheFrameRect( &g.rcResizeRect, FALSE );
  451.  
  452.                  ReleaseCapture();
  453.                  DrawTheFrameRect( NULL, FALSE );   // This cleans up
  454.                  ClipCursor( NULL );
  455.  
  456.                  MoveWindow( PlayerQueryFrameWindow(),
  457.                            g.rcResizeRect.left, g.rcResizeRect.top,
  458.                            g.rcResizeRect.right - g.rcResizeRect.left,
  459.                            g.rcResizeRect.bottom - g.rcResizeRect.top, TRUE );
  460.                 }
  461.  
  462.              return 0L;
  463.  
  464.          case WM_PAINT:
  465.                 // We paint the icon but QTW takes care of all the painting
  466.                 // otherwise.
  467.              if( pMovieData && IsIconic( hwndMovie ))
  468.                  return PaintTheIcon( hwndMovie, pMovieData );
  469.              break;  // break to DefMDIChildProc
  470.  
  471.          case WM_DESTROY:
  472.              if( ( lpOleData = PlayerQueryOleData()) && lpOleData->lpqtoleServer )
  473.                  PopulateOptionsStruct( hwndMovie, pMovieData );
  474.              break;  // break to DefMDIChildProc
  475.  
  476.          case WM_NCDESTROY:
  477.              if( !pMovieData )
  478.                  break;
  479.  
  480.              if( pMovieData->lpFilterProc )
  481.                 {MCSetActionFilter
  482.                              ( pMovieData->mcMovieController, NULL, 0L );
  483.                  FreeProcInstance( (FARPROC ) pMovieData->lpFilterProc );
  484.                  pMovieData->lpFilterProc = NULL;
  485.                 }
  486.  
  487.              if( pMovieData->hwndGetInfo )
  488.                  DestroyWindow( pMovieData->hwndGetInfo );
  489.  
  490.              if( pMovieData->mcMovieController )
  491.                  DisposeMovieController( pMovieData->mcMovieController );
  492.              if( pMovieData->mMovie )
  493.                  DisposeMovie( pMovieData->mMovie );
  494.  
  495.                 // Last instance destroys icon and grow box subclass proc
  496.              if( PlayerQueryNumMovies() <= 1 )
  497.                 {if( g.hmovieIcon )
  498.                      DestroyIcon( g.hmovieIcon );
  499.                  g.hmovieIcon = NULL;
  500.  
  501.                      // Free the grow box subclass proc
  502.                  if( g.lpNewGBProc )
  503.                     {FreeProcInstance( (FARPROC) g.lpNewGBProc );
  504.                      g.lpNewGBProc = NULL;
  505.                     }
  506.                  g.lpOldGBProc = NULL;
  507.                 }
  508.              else
  509.                 { // Check for duplicates
  510.                  g.wMovieCount  = 0;
  511.                  g.bCreating    = FALSE;
  512.                  g.hwndFirstDup = NULL;
  513.  
  514.                  if( lpfnEnumMovies = (WNDENUMPROC) MakeProcInstance
  515.                      ( (FARPROC) CheckDupEnumProc, PlayerQueryInstance()))
  516.                     {EnumChildWindows( PlayerQueryClientWindow(),
  517.                           lpfnEnumMovies, MAKELPARAM( hwndMovie, 0 ));
  518.                      FreeProcInstance( (FARPROC) lpfnEnumMovies );
  519.                     }
  520.  
  521.                    // if no dups, eliminate :1 on first
  522.                    // hwndFirstDup is set in CheckDupEnumProc
  523.                  if( ( g.wMovieCount == 1 ) && g.hwndFirstDup &&
  524.                             ( pFirstMovieData = (NPMOVIEDATA)
  525.                                        GetWindowWord( g.hwndFirstDup, 0 )))
  526.                     {pFirstMovieData->wDuplicationIndex = 0;
  527.                      SetWindowText( g.hwndFirstDup,
  528.                                         pFirstMovieData->szMovieName );
  529.                     }
  530.                 }
  531.  
  532.                 // Tell OLE that window is closed. Movie has been disposed
  533.                 // qtole.dll used hwndObject so don't null the handle in struct
  534.              pMovieData->qtoleOptions.mMovie = NULL;
  535.  
  536.              if( ( lpOleData = PlayerQueryOleData()) && lpOleData->lpqtoleServer )
  537.                  QTOLE_ClosingDocWnd( lpOleData,
  538.                                (LPQTOLE_OPTIONS) &pMovieData->qtoleOptions );
  539.  
  540.              LocalUnlock( hMovieData =
  541.                                    (HMOVIEDATA) LocalHandle( pMovieData ));
  542.              LocalFree( hMovieData );
  543.              SetWindowWord( hwndMovie, 0, 0);
  544.  
  545.                 // Update the movie count in the frame window globals
  546.              SendMessage( PlayerQueryFrameWindow(),
  547.                           WM_PLAYER_MOVIEDELETED, (WPARAM) hwndMovie, 0L );
  548.  
  549.              break;  // break to DefMDIChildProc
  550.  
  551.          }
  552.  
  553.       return DefMDIChildProc( hwndMovie, message, wParam, lParam );
  554.      }
  555.  
  556.  
  557. // Function: PlayerMovieCreate - process WM_CREATE message
  558. // --------------------------------------------------------------------
  559. // Parameters: HWND        hwndMovie;      Handle of movie window
  560. //             LPARAM      lParam;         lParam of WM_CREATE message
  561. //
  562. // Returns:    0 if OK, else returns -1 to kill app
  563. // --------------------------------------------------------------------
  564.    static LONG NEAR PlayerMovieCreate( HWND hwndMovie, LPARAM lParam )
  565.  
  566.      {NPMOVIEDATA        pMovieData;       // Temp -> to movie data struct
  567.       HMOVIEDATA         hMovieData;       // Handle to movie data struct
  568.       LPMDICREATESTRUCT  lpmdicreate;      // MDI create struct
  569.       MovieFile          movMovieFile;     // Movie file handle
  570.       char               szBuffer[MAX_PATH_LEN];  // Temp buffer
  571.       struct _stat       statbuf;          // File statictics struct
  572.       WORD               wIDString;        // Resource string id
  573.       DWORD              dwBytes;          // File size
  574.       OSErr              oserr;            // Error return
  575.       RECT               rcMovie;          // Movie rect
  576.       RECT               rcWindow;         // Window rect
  577.       RECT               rcController;     // Controller rect
  578.       POINT              ptCorner;         // Upper Left corner of movie wnd
  579.       WORD               wWidth;           // Width of window
  580.       WORD               wHeight;          // Height of window
  581.       RECT               rcclientClient;   // Client rect of MDI client wnd
  582.       int                nDiff;            // Temp
  583.       WNDENUMPROC        lpfnEnumMovies;   // -> to enumeration proc
  584.       LPSTR              lpName;           // Temp -> movie name
  585.       LONG               lStyle;           // Temp window style
  586.       UserData           udUserData;       // Handle to user data
  587.       HGLOBAL            ghMem;            // Global mem used to get 'loop' user data
  588.       LONG               lSizeData;        // Size of 'loop' user data
  589.       LPSTR              lpUserData;       // -> 'loop' user data
  590.       int                i;                // Loop counter
  591.       QTOLE_OPENWND      qtoleOpenWnd;     // Ole open wnd struct
  592.       LPQTOLE_OLEDATA    lpOleData;        // -> ole data
  593.       int                nLoop;
  594.  
  595.  
  596.       pMovieData = (NPMOVIEDATA) NULL;
  597.  
  598.       if( !(hMovieData = (HMOVIEDATA)
  599.                             LocalAlloc( LPTR, sizeof( MOVIEDATASTRUCT ))))
  600.          {CommonTellUser( PlayerQueryResources(),
  601.                                   PLAYER_STRING_NOMEMORY, NULL, MB_OK );
  602.           goto Failed;
  603.          }
  604.       pMovieData = (NPMOVIEDATA) LocalLock( hMovieData );
  605.       SetWindowWord( hwndMovie, 0, (WORD) pMovieData );
  606.  
  607.    // mdi struct filled before call to MDI create in LaunchMovieWnd
  608.       lpmdicreate = (LPMDICREATESTRUCT)
  609.                                ((LPCREATESTRUCT) lParam)->lpCreateParams;
  610.  
  611.       lstrcpy( pMovieData->szMoviePath, (LPSTR) lpmdicreate -> lParam );
  612.       lstrcpy( pMovieData->szMovieName, (LPSTR) lpmdicreate -> szTitle );
  613.  
  614.    // Strip off and save extension so that name fits better
  615.    // on title bar of window
  616.       pMovieData->szMovieExt[0] = '\0';
  617.       lpName = pMovieData->szMovieName;
  618.       while( *lpName )
  619.          {if( *lpName == '.' )
  620.             {lstrcpy( pMovieData->szMovieExt, lpName );
  621.              *lpName = '\0';
  622.              SetWindowText( hwndMovie, pMovieData->szMovieName );
  623.              break;
  624.             }
  625.           else
  626.             lpName = AnsiNext( lpName );
  627.          }
  628.  
  629.       if( ( oserr = OpenMovieFile( pMovieData->szMoviePath,
  630.                                           &movMovieFile, OF_READ )) == 0 )
  631.          {oserr = NewMovieFromFile( &pMovieData->mMovie,
  632.                                           movMovieFile, NULL, NULL, 0, NULL );
  633.           CloseMovieFile( movMovieFile );
  634.          }
  635.  
  636.       if( oserr )
  637.          {if( oserr == insufficientMemory )
  638.               wIDString = PLAYER_STRING_NOMEMORY;
  639.           else if( oserr == invalidDataRef )
  640.               wIDString = PLAYER_STRING_INVALIDDATAREF;
  641.           else
  642.               wIDString = PLAYER_STRING_NEWMOVIEERR;
  643.  
  644.           CommonTellUser( PlayerQueryResources(),
  645.                          wIDString, PLAYER_STRING_CAPTION,
  646.                                   MB_OK, (LPSTR) lpmdicreate -> szTitle );
  647.           goto Failed;
  648.          }
  649.  
  650.     // Check for duplicates. Fix up titles if necessary
  651.            // Initialize globals used during enumeration
  652.       g.wMovieCount = 1;
  653.       g.bCreating =  TRUE;
  654.       if( ( PlayerQueryNumMovies() > 0 ) &&
  655.                ( lpfnEnumMovies = (WNDENUMPROC) MakeProcInstance
  656.                      ( (FARPROC) CheckDupEnumProc, PlayerQueryInstance())))
  657.          {EnumChildWindows( PlayerQueryClientWindow(),
  658.                           lpfnEnumMovies, MAKELPARAM( hwndMovie, 0 ));
  659.           FreeProcInstance( (FARPROC) lpfnEnumMovies );
  660.  
  661.              // Fix up title if duplicate
  662.              // Title of 1st dup is fixed up during enum
  663.           if( g.wMovieCount > 1 )
  664.              {pMovieData->wDuplicationIndex = g.wMovieCount;
  665.               wsprintf( szBuffer, "%s:%u",
  666.                                    (LPSTR) pMovieData->szMovieName,
  667.                                             pMovieData->wDuplicationIndex );
  668.               SetWindowText( hwndMovie, szBuffer );
  669.              }
  670.          }
  671.  
  672.     // file size  Note: _stat path name is in OEM char set
  673.       lstrcpy( szBuffer, pMovieData->szMoviePath );
  674.       AnsiToOem( szBuffer, szBuffer );
  675.       if( (_stat( szBuffer, &statbuf )) == 0 )
  676.           {if( statbuf.st_size < 1000L )
  677.               {dwBytes = (DWORD) statbuf.st_size;
  678.                wIDString = PLAYER_STRING_SIZEBYTES;
  679.               }
  680.            else
  681.               {dwBytes = (DWORD) ( statbuf.st_size / 1000L );
  682.                wIDString = PLAYER_STRING_SIZEKBYTES;
  683.               }
  684.  
  685.            LoadString( PlayerQueryResources(),
  686.                                  wIDString, szBuffer, sizeof( szBuffer ));
  687.            wsprintf( pMovieData->szFileSize, szBuffer, dwBytes );
  688.           }
  689.  
  690.       pMovieData->bSoundOnly = FALSE;
  691.       pMovieData->idMovieInfo.idSize = sizeof( ImageDescription );
  692.       oserr = GetVideoInfo( pMovieData->mMovie, &pMovieData->idMovieInfo );
  693.       if( oserr == noVideoTrackInMovie )
  694.          {pMovieData->bSoundOnly = TRUE;
  695.          }
  696.       else if( oserr )
  697.          {CommonTellUser( PlayerQueryResources(),
  698.                      PLAYER_STRING_NOINFO, PLAYER_STRING_CAPTION, MB_OK );
  699.           goto Failed;
  700.          }
  701.  
  702.       pMovieData->sdSoundInfo.descSize = sizeof( SoundDescription );
  703.       pMovieData->oserrSoundInfo =
  704.               GetSoundInfo( pMovieData->mMovie, &pMovieData->sdSoundInfo );
  705.  
  706.  
  707.         // Set copy option default values
  708.       SetOptionsDefaults( hwndMovie, pMovieData );
  709.  
  710.         // Instantiate the movie controller
  711.       if( !pMovieData->bSoundOnly )  // Call only if there is video
  712.          {GetMovieBox( pMovieData->mMovie, &rcMovie );
  713.           OffsetRect( &rcMovie, -rcMovie.left, -rcMovie.top );
  714.  
  715.             // Now resize window if default option is half or double size
  716.           if( pMovieData->qtoleOptions.bSizeHalf )
  717.              {rcMovie.right  /= 2;
  718.               rcMovie.bottom /= 2;
  719.              }
  720.           else if( pMovieData->qtoleOptions.bSizeDouble )
  721.              {rcMovie.right  *= 2;
  722.               rcMovie.bottom *= 2;
  723.              }
  724.          }
  725.  
  726.         // Movie with no video or no rect gets a default width to pass to
  727.         // NewMovieController
  728.       if( pMovieData->bSoundOnly || IsRectEmpty( &rcMovie ))
  729.          {rcMovie.left = rcMovie.top = 0;
  730.           rcMovie.right = 8 * GetSystemMetrics( SM_CXVSCROLL );
  731.           rcMovie.bottom = 0;
  732.          }
  733.  
  734.       if( !( pMovieData->mcMovieController =
  735.                  NewMovieController( pMovieData->mMovie, &rcMovie,
  736.                          mcTopLeftMovie | mcScaleMovieToFit, hwndMovie )))
  737.          {CommonTellUser( PlayerQueryResources(),
  738.                  PLAYER_STRING_NOCONTROLLER, PLAYER_STRING_CAPTION, MB_OK );
  739.           goto Failed;
  740.          }
  741.       MCDoAction( pMovieData->mcMovieController, mcActionPlay, (LPVOID) 0 );
  742.  
  743.         // Subclass the movie controller grow box for use when a
  744.         // movie window is maximized
  745.       pMovieData->bGrowBoxSubclassed =
  746.                           SubclassTheGrowBox( hwndMovie, pMovieData );
  747.  
  748.         // Override loop mode depending on user data
  749.       ghMem = NULL;
  750.       nLoop = 0;
  751.       if( ( udUserData = GetMovieUserData( pMovieData->mMovie )) &&
  752.                     ( CountUserDataType( udUserData,
  753.                                QTFOURCC( 'L', 'O', 'O', 'P' )) > 0 ))
  754.          {pMovieData->qtoleOptions.bLoop           = TRUE;
  755.           pMovieData->qtoleOptions.bLoopPalindrome = FALSE;
  756.           if( ( ghMem = GlobalAlloc( GHND, 16L )) &&
  757.                 !GetUserData( udUserData, &ghMem,
  758.                      QTFOURCC( 'L', 'O', 'O', 'P' ), 1L, &lSizeData ) &&
  759.                           ( lSizeData > 0L ))
  760.              {lpUserData = (LPSTR) GlobalLock( ghMem );
  761.               for( i=0; i < lSizeData; i++ )
  762.                 {if( *lpUserData++ != '\0' )
  763.                     {pMovieData->qtoleOptions.bLoop           = FALSE;
  764.                      pMovieData->qtoleOptions.bLoopPalindrome = TRUE;
  765.                      break;
  766.                     }
  767.                 }
  768.               GlobalUnlock( ghMem );
  769.              }
  770.           if( ghMem )
  771.               GlobalFree( ghMem );
  772.          }
  773.  
  774.          // Now tell the movie controller about the loop mode
  775.       MCDoAction( pMovieData->mcMovieController, mcActionSetLooping,
  776.                  (LPVOID) ( pMovieData->qtoleOptions.bLoop ||
  777.                                    pMovieData->qtoleOptions.bLoopPalindrome ));
  778.       MCDoAction( pMovieData->mcMovieController, mcActionSetLoopIsPalindrome,
  779.                           (LPVOID) pMovieData->qtoleOptions.bLoopPalindrome );
  780.  
  781.         // Assume that the controller is attached
  782.         // Get the default UL corner of window
  783.       GetWindowRect( hwndMovie, &rcWindow );
  784.       MapWindowPoints( HWND_DESKTOP, PlayerQueryClientWindow(),
  785.                                                 (LPPOINT) &rcWindow, 2 );
  786.       ptCorner = *((LPPOINT) &rcWindow.left );
  787.  
  788.         // This includes the movie AND the moviecontroller rect
  789.       MCGetControllerBoundsRect
  790.                           ( pMovieData->mcMovieController, &rcController );
  791.       rcWindow = rcController;
  792.         // At this point rcController == client rect of window
  793.  
  794.         // Save controller height
  795.       g.wMovieControllerHeight =
  796.                          ( rcWindow.bottom - rcWindow.top ) -
  797.                                          ( rcMovie.bottom - rcMovie.top );
  798.  
  799.         // Remove maximize box if sound only movie
  800.       if( pMovieData->bSoundOnly )
  801.          {lStyle = GetWindowLong( hwndMovie, GWL_STYLE );
  802.           lStyle &= ~WS_MAXIMIZEBOX;
  803.           SetWindowLong( hwndMovie, GWL_STYLE, lStyle );
  804.          }
  805.  
  806.       AdjustWindowRect( &rcWindow,
  807.                            GetWindowLong( hwndMovie, GWL_STYLE ), FALSE );
  808.         // rcWindow now contains the size of the window
  809.  
  810.       wWidth  = rcWindow.right  - rcWindow.left;
  811.       wHeight = rcWindow.bottom - rcWindow.top;
  812.       OffsetRect( &rcWindow, ptCorner.x - rcWindow.left,
  813.                                      ptCorner.y - rcWindow.top );
  814.          // rcWindow now contains the resized window positioned so that
  815.          // the UL corner is at the MDI default position
  816.  
  817.          // Now stash some dimensions needed later. Only need to do this once
  818.       if( pMovieData->bSoundOnly && !g.wSoundOnlyDefWidth )
  819.          {g.wSoundOnlyDefWidth = wWidth;
  820.          }
  821.       if( !g.wSides )
  822.          {g.wSides    = ( rcWindow.right - rcWindow.left ) -
  823.                               ( rcController.right - rcController.left );
  824.           g.wTBBorder = ( rcWindow.bottom - rcWindow.top ) -
  825.                               ( rcController.bottom - rcController.top );
  826.           g.wTopAndBottom = g.wMovieControllerHeight + g.wTBBorder;
  827.          }
  828.  
  829.  
  830.          // Now see if it will fit on screen.
  831.       GetClientRect( PlayerQueryClientWindow(), &rcclientClient );
  832.       if( rcWindow.right > rcclientClient.right )
  833.          {    // extends beyond right border
  834.               // Try to shift it to the left
  835.           nDiff = rcclientClient.right - wWidth;
  836.           rcWindow.left  = max( 0, nDiff );
  837.           rcWindow.right = rcWindow.left + wWidth;
  838.          }
  839.  
  840.       if( rcWindow.bottom > rcclientClient.bottom )
  841.          {    // extends beyond bottom
  842.               // Try to shift it up
  843.           nDiff = rcclientClient.bottom - wHeight;
  844.           rcWindow.top    = max( 0, nDiff );
  845.           rcWindow.bottom = rcWindow.top + wHeight;
  846.          }
  847.  
  848.          // Resize the window after disabling WM_SIZE processing
  849.          // In the unusual case that the controller is smaller than
  850.          // the smallest possible client, we stretch the controller
  851.       pMovieData->bDisableSizeMsgProcessing = TRUE;
  852.       MoveWindow( hwndMovie,
  853.                      rcWindow.left, rcWindow.top, wWidth, wHeight, FALSE );
  854.  
  855.          // If movie is smaller than minimum window size, resize movie to
  856.          // fill the window
  857.       GetClientRect( hwndMovie, &rcWindow );
  858.       if( !EqualRect( &rcWindow, &rcController ))
  859.           MCSetControllerBoundsRect
  860.                           ( pMovieData->mcMovieController, &rcWindow );
  861.  
  862.          // Size message turns this off, turn in on again for next
  863.          // WM_SIZE message generated by standard "create a window" processing
  864.       pMovieData->bDisableSizeMsgProcessing = TRUE;
  865.  
  866.          // Post message to activate the movie
  867.          // Post message is used to avoid a extra paint of the movie which
  868.          // causes a flash during the window creation
  869.          // SendMessage is called if PostMessage fails
  870.       if( !PostMessage( hwndMovie, WM_PLAYER_ACTIVATEMOVIE, 0, 0L ))
  871.           SendMessage( hwndMovie, WM_PLAYER_ACTIVATEMOVIE, 0, 0L );
  872.  
  873.         // Set Action filter to look for selection changes and grow box resizing.
  874.         // Do this after earlier resizing to avoid having to block filter messages
  875.         // generated during creation
  876.       if( pMovieData->lpFilterProc =
  877.               (MCActionFilter) MakeProcInstance
  878.                             ( (FARPROC) ActionFilter, PlayerQueryInstance()))
  879.          {MCSetActionFilter( pMovieData->mcMovieController,
  880.                  pMovieData->lpFilterProc, MAKELONG( pMovieData, hwndMovie ));
  881.          }
  882.  
  883.         // Tell qtole.dll that movie has been opened
  884.       if( ( lpOleData = PlayerQueryOleData()) && lpOleData->lpqtoleServer )
  885.          {qtoleOpenWnd.lStructSize  = sizeof( qtoleOpenWnd );
  886.           qtoleOpenWnd.lVersion     = VERSION_1;
  887.           qtoleOpenWnd.wObjectType  = MOVIE_OBJECT;
  888.           qtoleOpenWnd.hwndObject   = hwndMovie;
  889.           qtoleOpenWnd.lpObjectPath = pMovieData->szMoviePath;
  890.           qtoleOpenWnd.lpObjectName = pMovieData->szMovieName;
  891.  
  892.           QTOLE_OpeningNewObjectWnd( lpOleData, &qtoleOpenWnd );
  893.          }
  894.  
  895.       return  0L;
  896.  
  897.  Failed:
  898.       SetWindowWord( hwndMovie, 0, 0 );
  899.       if( pMovieData )
  900.           LocalUnlock( hMovieData );
  901.       if( hMovieData )
  902.           LocalFree  ( hMovieData );
  903.  
  904.       return -1;
  905.  
  906.      }
  907.  
  908. // Function: CheckDupEnumProc - Checks for duplicate pictures and
  909. //                              fixes up titles if there are any
  910. // --------------------------------------------------------------------
  911. // Parameters: As required by Microsoft Windows
  912. //
  913. // Returns:    Always TRUE;
  914. // --------------------------------------------------------------------
  915.    BOOL __export CALLBACK CheckDupEnumProc( HWND hwnd, LPARAM lParam )
  916.  
  917.    // Look for duplicate pictures. Test is on path rather than just name
  918.  
  919.      {char            szBuffer[50];      // Temp buffer
  920.       HWND            hwndActiveMovie;   // Handle of active movie wnd
  921.       NPMOVIEDATA     pMovieData;        // -> enum wnd movie data struct
  922.       NPMOVIEDATA     pActiveMovieData;  // -> active wnd movie data struct
  923.  
  924.          // Skip active movie
  925.       if( ( hwndActiveMovie = (HWND) LOWORD( lParam )) == hwnd )
  926.           return TRUE;
  927.  
  928.       if( !GetClassName( hwnd, szBuffer, sizeof( szBuffer )) ||
  929.                               lstrcmpi( szBuffer, PLAYER_MOVIE_CLASS ))
  930.           return TRUE;
  931.  
  932.       pMovieData = (NPMOVIEDATA) GetWindowWord( hwnd, 0 );
  933.       pActiveMovieData = (NPMOVIEDATA) GetWindowWord( hwndActiveMovie, 0 );
  934.       if( !pMovieData || !pActiveMovieData )
  935.           return TRUE;
  936.  
  937.       if( !lstrcmpi( pMovieData->szMoviePath,
  938.                                          pActiveMovieData->szMoviePath ))
  939.          {    // Found a duplicate
  940.           g.wMovieCount++;
  941.           if( g.bCreating )
  942.              {if( pMovieData->wDuplicationIndex == 0 )
  943.                  {pMovieData->wDuplicationIndex = 1;
  944.                   wsprintf( szBuffer, "%s:%u",
  945.                                     (LPSTR) pMovieData->szMovieName,
  946.                                            pMovieData->wDuplicationIndex );
  947.                   SetWindowText( hwnd, szBuffer );
  948.                  }
  949.              }
  950.           else
  951.              {if( pMovieData->wDuplicationIndex >
  952.                                       pActiveMovieData->wDuplicationIndex )
  953.                  {pMovieData->wDuplicationIndex--;
  954.                   wsprintf( szBuffer, "%s:%u",
  955.                                      (LPSTR) pMovieData->szMovieName,
  956.                                            pMovieData->wDuplicationIndex );
  957.                   SetWindowText( hwnd, szBuffer );
  958.                  }
  959.               if( pMovieData->wDuplicationIndex == 1 )
  960.                   g.hwndFirstDup = hwnd;
  961.              }
  962.  
  963.           if( pMovieData->hwndGetInfo &&
  964.                  !PostMessage( pMovieData->hwndGetInfo,
  965.                                WM_PLAYER_INFO_UPDATEFILENAME, 0, 0L ))
  966.               SendMessage( pMovieData->hwndGetInfo,
  967.                                WM_PLAYER_INFO_UPDATEFILENAME, 0, 0L );
  968.          }
  969.  
  970.       return TRUE;
  971.      }
  972.  
  973.  
  974. // Function: PlayerEditCommands - Process WM_COMMAND, Edit popup messages
  975. // --------------------------------------------------------------------
  976. // Parameters: HWND   hwndMovie;      Handle of movie window
  977. //             WORD   wIDItem;        Menu or control id
  978. //             WORD   wNotifyCode;    notification message
  979. //
  980. // Returns:    LONG   generally 0L
  981. // --------------------------------------------------------------------
  982.    static LONG NEAR PlayerEditCommands
  983.                        (HWND hwndMovie, WPARAM wIDItem, WORD wNotifyCode )
  984.  
  985.      {NPMOVIEDATA      pMovieData;      // -> movie data struct
  986.       TimeRecord       trZeroTime;      // Zero time
  987.       PicHandle        phFrame;         // Pic handle of copied frame
  988.       DIBHandle        hbmpDIB;         // Handle of DIB bitmap passed to clipboard
  989.       OSErr            oserr;           // Errror return value
  990.       WORD             wIDString;       // ID of error string
  991.       HDC              hdc;             // Device context of window
  992.       HDC              hdcMem;          // Memory dc
  993.       ImageDescription idPicInfo;       // Image description struct
  994.       HBITMAP          hbmpCompatible;  // Mem bitmap
  995.       HBITMAP          hbmpSave;        // Prev bitmap
  996.       RECT             rcFrame;         // Rect of frame being copied
  997.       TimeRecord       trMovieTime;     // Temp time record
  998.       HPALETTE         hpal;            // Palette handle
  999.       LPQTOLE_OLEDATA  lpOleData;       // -> ole data
  1000.  
  1001.       if( !(pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 )))
  1002.          {CommonTellUser( PlayerQueryResources(),
  1003.                   PLAYER_STRING_NOMOVIEDATA, PLAYER_STRING_CAPTION, MB_OK );
  1004.           return 0L;
  1005.          }
  1006.  
  1007.       switch( wIDItem )
  1008.         {case PLAYER_EDIT_COPY:
  1009.             if( IsIconic( hwndMovie ))
  1010.                 return 0L;
  1011.  
  1012.                // If ole, let ole do the copy
  1013.             if( ( lpOleData = PlayerQueryOleData()) && lpOleData->lpqtoleServer )
  1014.                {PopulateOptionsStruct( hwndMovie, pMovieData );
  1015.  
  1016.                 QTOLE_Copy( lpOleData, (LPQTOLE_OPTIONS) &pMovieData->qtoleOptions );
  1017.  
  1018.                // We must compensate for an error in certain drivers by
  1019.                // resetting the palette back the way we found it
  1020.                 MCDoAction( pMovieData->mcMovieController,
  1021.                             mcActionSetFlags, (LPVOID) mcFlagsUseWindowPalette );
  1022.                }
  1023.             else     // No ole so do copy here
  1024.                {hdcMem = NULL;
  1025.                 hbmpCompatible = NULL;
  1026.                 hbmpSave = NULL;
  1027.                 phFrame  = NULL;
  1028.  
  1029.                 if( !( hdc = GetDC( hwndMovie )) ||
  1030.                       !( hdcMem = CreateCompatibleDC( hdc )) ||
  1031.                        !( phFrame = GetMoviePict( pMovieData->mMovie,
  1032.                          GetMovieTime( pMovieData->mMovie, &trMovieTime ))))
  1033.                    {wIDString = PLAYER_STRING_COPYFAILED;
  1034.                     goto CopyFailed;
  1035.                    }
  1036.  
  1037.                 if( oserr = GetPictureInfo( phFrame, &idPicInfo ))
  1038.                    {wIDString = PLAYER_STRING_COPYFAILED;
  1039.                     goto CopyFailed;
  1040.                    }
  1041.  
  1042.                 if( !( hbmpCompatible = CreateCompatibleBitmap( hdc,
  1043.                                      idPicInfo.width, idPicInfo.height )))
  1044.                    {wIDString = PLAYER_STRING_NOMEMORY;
  1045.                     goto CopyFailed;
  1046.                    }
  1047.  
  1048.                 if( !( hbmpSave = SelectObject( hdcMem, hbmpCompatible )))
  1049.                    {wIDString = PLAYER_STRING_COPYFAILED;
  1050.                     goto CopyFailed;
  1051.                    }
  1052.  
  1053.                 rcFrame.left = rcFrame.top = 0;
  1054.                 rcFrame.right  = idPicInfo.width;
  1055.                 rcFrame.bottom = idPicInfo.height;
  1056.  
  1057.                 if( oserr = DrawPicture( hdcMem, phFrame, &rcFrame, NULL ))
  1058.                    {wIDString = PLAYER_STRING_COPYFAILED;
  1059.                     goto CopyFailed;
  1060.                    }
  1061.                 SelectObject( hdcMem, hbmpSave );
  1062.                 hbmpSave = NULL;
  1063.                 DeleteDC( hdcMem );
  1064.                 hdcMem = NULL;
  1065.  
  1066.                 OpenClipboard( hwndMovie );
  1067.                 EmptyClipboard();
  1068.                 if( !SetClipboardData( CF_BITMAP, hbmpCompatible ))
  1069.                    {wIDString = PLAYER_STRING_COPYFAILED;
  1070.                     goto CopyFailed;
  1071.                    }
  1072.                 hbmpCompatible = NULL;   // Now belongs to clipboard
  1073.  
  1074.                   // Now add palette if movie has a palette
  1075.                 if( ( hpal = GetPicturePalette( phFrame )) &&
  1076.                             !SetClipboardData( CF_PALETTE, hpal ))
  1077.                     DeleteObject( hpal );
  1078.                 hpal = NULL;
  1079.  
  1080.                   // Now try to add DIBitmap to clipboard
  1081.                 if( ( hbmpDIB = PictureToDIB( phFrame )) &&
  1082.                                     !SetClipboardData( CF_DIB, hbmpDIB ))
  1083.                     GlobalFree( hbmpDIB );
  1084.                 hbmpDIB = NULL;
  1085.  
  1086.                 CloseClipboard();
  1087.                 if( phFrame )
  1088.                     DisposePicture( phFrame );
  1089.                 ReleaseDC( hwndMovie, hdc );
  1090.  
  1091.                 return 0L;
  1092.  
  1093.       CopyFailed:
  1094.                 CommonTellUser( PlayerQueryResources(),
  1095.                                wIDString, PLAYER_STRING_CAPTION, MB_OK );
  1096.                 if( hbmpSave )
  1097.                     SelectObject( hdcMem, hbmpSave );
  1098.                 if( hdc )
  1099.                     ReleaseDC( hwndMovie, hdc );
  1100.                 if( hdcMem )
  1101.                     DeleteDC( hdcMem );
  1102.                 if( hbmpCompatible )
  1103.                     DeleteObject( hbmpCompatible );
  1104.                 if( phFrame )
  1105.                     DisposePicture( phFrame );
  1106.                 if( hbmpDIB )
  1107.                     GlobalFree( hbmpDIB );
  1108.                }
  1109.  
  1110.             return 0L;
  1111.  
  1112.          case PLAYER_EDIT_OPTIONS:
  1113.             PopulateOptionsStruct( hwndMovie, pMovieData );
  1114.  
  1115.             if( PlayerGetOptions( hwndMovie, &pMovieData->qtoleOptions ))
  1116.                 UpdateMovieForOptions( hwndMovie, pMovieData, FALSE );
  1117.  
  1118.             return 0L;
  1119.  
  1120.          case PLAYER_EDIT_CANCELSEL:
  1121.             trZeroTime.scale = GetMovieTimeScale( pMovieData->mMovie );
  1122.             trZeroTime.value.dwHi = 0L;
  1123.  
  1124.             trZeroTime.value.dwLo = (DWORD) -1L;
  1125.             trZeroTime.base       = TIMEBASE_DEFAULT;
  1126.                 // Set beginning of selection to zero
  1127.             MCDoAction( pMovieData->mcMovieController,
  1128.                          mcActionSetSelectionBegin, (LPVOID) &trZeroTime );
  1129.                 // Set duration to zero
  1130.             trZeroTime.value.dwLo = 0L;
  1131.             trZeroTime.base       = NULL;
  1132.             MCDoAction( pMovieData->mcMovieController,
  1133.                       mcActionSetSelectionDuration, (LPVOID) &trZeroTime );
  1134.  
  1135.             return 0L;
  1136.         }
  1137.  
  1138.       return 0L;      // should never get here
  1139.  
  1140.      }
  1141.  
  1142.  
  1143. // Function: PlayerMovieCommands - Process WM_COMMAND, Movie popup messages
  1144. // --------------------------------------------------------------------
  1145. // Parameters: HWND          hwndMovie;      Handle of movie window
  1146. //             WORD          wIDItem;        Menu or control id
  1147. //             WORD          wNotifyCode;    notification message
  1148. //
  1149. // Returns:    LONG   generally 0L
  1150. // --------------------------------------------------------------------
  1151.    static LONG NEAR PlayerMovieCommands
  1152.                      ( HWND hwndMovie, WPARAM wIDItem, WORD wNotifyCode )
  1153.  
  1154.      {NPMOVIEDATA   pMovieData;           // -> movie data struct
  1155.       DLGPROC       lpDlgProc;            // -> info dialog proc function
  1156.       HWND          hwndInfoDialog;       // HWND of info dialog box
  1157.       TimeRecord    trPosterTime;         // Poster time
  1158.       BOOL          bPlaySelectionOnly;   // Flag
  1159.  
  1160.  
  1161.       if( !(pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 )))
  1162.          {CommonTellUser( PlayerQueryResources(),
  1163.                   PLAYER_STRING_NOMOVIEDATA, PLAYER_STRING_CAPTION, MB_OK );
  1164.           return 0L;
  1165.          }
  1166.  
  1167.       switch( wIDItem )
  1168.          {case PLAYER_MOVIE_GETINFO:
  1169.              if( pMovieData->hwndGetInfo )
  1170.                  SetFocus( pMovieData->hwndGetInfo );
  1171.              else if( !(lpDlgProc = (DLGPROC) MakeProcInstance
  1172.                       ( (FARPROC) GetInfoDlgProc, PlayerQueryInstance())) ||
  1173.                          !(hwndInfoDialog =
  1174.                               CreateDialog( PlayerQueryResources(),
  1175.                                   MAKEINTRESOURCE( PLAYER_DLG_GETINFO ),
  1176.                                     PlayerQueryFrameWindow(), lpDlgProc )))
  1177.                 {CommonTellUser( PlayerQueryResources(),
  1178.                                  PLAYER_STRING_NOMEMORY, NULL, MB_OK );
  1179.                 }
  1180.  
  1181.              return 0L;
  1182.  
  1183.           case PLAYER_MOVIE_STOPATEND:
  1184.              MCDoAction( pMovieData->mcMovieController,
  1185.                             mcActionSetLoopIsPalindrome, (LPVOID) FALSE );
  1186.              MCDoAction( pMovieData->mcMovieController,
  1187.                                      mcActionSetLooping, (LPVOID) FALSE );
  1188.              return 0L;
  1189.  
  1190.           case PLAYER_MOVIE_LOOP:
  1191.              MCDoAction( pMovieData->mcMovieController,
  1192.                                        mcActionSetLooping, (LPVOID) TRUE );
  1193.              MCDoAction( pMovieData->mcMovieController,
  1194.                              mcActionSetLoopIsPalindrome, (LPVOID) FALSE );
  1195.              return 0L;
  1196.  
  1197.          case PLAYER_MOVIE_BACKANDFORTH:
  1198.              MCDoAction( pMovieData->mcMovieController,
  1199.                                        mcActionSetLooping, (LPVOID) TRUE );
  1200.              MCDoAction( pMovieData->mcMovieController,
  1201.                               mcActionSetLoopIsPalindrome, (LPVOID) TRUE );
  1202.              return 0L;
  1203.  
  1204.          case PLAYER_MOVIE_PLAYSELONLY:
  1205.              MCDoAction( pMovieData->mcMovieController,
  1206.                                  mcActionGetPlaySelection,
  1207.                                            (LPVOID) &bPlaySelectionOnly );
  1208.  
  1209.              MCDoAction( pMovieData->mcMovieController,
  1210.                                  mcActionSetPlaySelection,
  1211.                                            (LPVOID) !bPlaySelectionOnly );
  1212.              return 0L;
  1213.  
  1214.  
  1215.       // For next 3 cases, if window is maximized or minimized, we need to
  1216.       // restore before resizing so that Windows knows that the window is
  1217.       // no longer maximized or minimized
  1218.  
  1219.          case PLAYER_MOVIE_HALFSIZE:
  1220.              if( ( pMovieData->wMinMaxEtc == SIZE_MAXIMIZED ) ||
  1221.                         ( pMovieData->wMinMaxEtc == SIZE_MINIMIZED ))
  1222.                  ShowWindow( hwndMovie, SW_SHOWNORMAL );
  1223.  
  1224.              return ResizeMovieAndWindow( hwndMovie, TRUE, pMovieData,
  1225.                               pMovieData->idMovieInfo.width / 2,
  1226.                                   pMovieData->idMovieInfo.height / 2 );
  1227.  
  1228.          case PLAYER_MOVIE_NORMALSIZE:
  1229.              if( ( pMovieData->wMinMaxEtc == SIZE_MAXIMIZED ) ||
  1230.                         ( pMovieData->wMinMaxEtc == SIZE_MINIMIZED ))
  1231.                  ShowWindow( hwndMovie, SW_SHOWNORMAL );
  1232.  
  1233.              return ResizeMovieAndWindow( hwndMovie, TRUE, pMovieData,
  1234.                                     pMovieData->idMovieInfo.width,
  1235.                                          pMovieData->idMovieInfo.height );
  1236.  
  1237.          case PLAYER_MOVIE_DOUBLESIZE:
  1238.              if( ( pMovieData->wMinMaxEtc == SIZE_MAXIMIZED ) ||
  1239.                         ( pMovieData->wMinMaxEtc == SIZE_MINIMIZED ))
  1240.                  ShowWindow( hwndMovie, SW_SHOWNORMAL );
  1241.  
  1242.             return ResizeMovieAndWindow( hwndMovie, TRUE, pMovieData,
  1243.                               pMovieData->idMovieInfo.width * 2,
  1244.                                       pMovieData->idMovieInfo.height * 2 );
  1245.  
  1246.          case PLAYER_MOVIE_SHOWPOSTER:
  1247.             trPosterTime.value.dwHi = 0L;
  1248.             trPosterTime.value.dwLo =
  1249.                                  GetMoviePosterTime( pMovieData->mMovie );
  1250.             trPosterTime.scale = GetMovieTimeScale( pMovieData->mMovie );
  1251.             trPosterTime.base  = TIMEBASE_DEFAULT;
  1252.  
  1253.                 // Stop the movie
  1254.             MCDoAction( pMovieData->mcMovieController,
  1255.                                                 mcActionPlay, (LPVOID) 0 );
  1256.                 // Go to poster time
  1257.             MCDoAction( pMovieData->mcMovieController,
  1258.                                 mcActionGoToTime, (LPVOID) &trPosterTime );
  1259.             return 0L;
  1260.         }
  1261.  
  1262.       return 0L;      // should never get here
  1263.  
  1264.      }
  1265.  
  1266. //// the following are some utility routines
  1267.  
  1268. // Function: ActivateTheController - Activates or deactivates the movie
  1269. //                                   controller
  1270. // --------------------------------------------------------------------
  1271. // Parameters: HWND         hwndMovie       Handle of movie window
  1272. //             NPMOVIEDATA  pMovieData      -> to movie data struct
  1273. //             BOOL         bActivate       Activate flag
  1274. //
  1275. // Returns:    VOID
  1276. // --------------------------------------------------------------------
  1277.    static VOID NEAR ActivateTheController
  1278.                 ( HWND hwndMovie, NPMOVIEDATA pMovieData, BOOL bActivate )
  1279.  
  1280.      {short          nVol;              // Sound volume
  1281.  
  1282.       if( bActivate && ( hwndMovie != (HWND) SendMessage
  1283.                     ( PlayerQueryClientWindow(), WM_MDIGETACTIVE, 0, 0L )))
  1284.           return;
  1285.  
  1286.       MCActivate( pMovieData->mcMovieController, hwndMovie, bActivate );
  1287.  
  1288.       MCDoAction( pMovieData->mcMovieController,
  1289.                            mcActionSetKeysEnabled, (LPVOID) bActivate );
  1290.       if( bActivate )   // RealizePalette only if activating
  1291.          {MCDoAction( pMovieData->mcMovieController,
  1292.                      mcActionSetFlags, (LPVOID) mcFlagsUseWindowPalette );
  1293.             // InvalidateRect is needed to cause repainting in certain
  1294.             // situations when the window is iconic
  1295.           InvalidateRect( hwndMovie, NULL, TRUE );
  1296.          }
  1297.  
  1298.       MCDoAction( pMovieData->mcMovieController,
  1299.                                        mcActionGetVolume, (LPVOID) &nVol );
  1300.       if( ( bActivate && ( nVol < 0 )) || ( !bActivate && ( nVol > 0 )))
  1301.           MCDoAction( pMovieData->mcMovieController,
  1302.                                        mcActionSetVolume, (LPVOID) -nVol );
  1303.      }
  1304.  
  1305.  
  1306.  
  1307. // Function: StartTheMovie - Starts the movie
  1308. // --------------------------------------------------------------------
  1309. // Parameters: NPMOVIEDATA  pMovieData      -> movie data struct
  1310. //
  1311. // Returns:    LONG         always 0L
  1312. // --------------------------------------------------------------------
  1313.    static LONG NEAR StartTheMovie( NPMOVIEDATA pMovieData )
  1314.  
  1315.      {  // Reactivate the movie
  1316.       SetMovieActive( pMovieData->mMovie, TRUE );
  1317.         // Restart the movie if it was playing
  1318.       if( pMovieData->lfxSavePlayRate )
  1319.           MCDoAction( pMovieData->mcMovieController,
  1320.                 mcActionPlay, (LPVOID) pMovieData->lfxSavePlayRate );
  1321.  
  1322.       return 0L;
  1323.      }
  1324.  
  1325. // Function: StopTheMovie - Stops the movie
  1326. // --------------------------------------------------------------------
  1327. // Parameters: NPMOVIEDATA  pMovieData      -> movie data struct
  1328. //
  1329. // Returns:    LONG         always 0L
  1330. // --------------------------------------------------------------------
  1331.    static LONG NEAR StopTheMovie( NPMOVIEDATA pMovieData )
  1332.  
  1333.      {  // save the play rate
  1334.       MCDoAction( pMovieData->mcMovieController,
  1335.               mcActionGetPlayRate, (LPVOID) &pMovieData->lfxSavePlayRate );
  1336.         // Stop the movie
  1337.       MCDoAction( pMovieData->mcMovieController,
  1338.                                       mcActionPlay, (LPVOID) 0 );
  1339.         // Deactivate movie to prevent painting over the icon
  1340.       SetMovieActive( pMovieData->mMovie, FALSE );
  1341.  
  1342.       return 0L;
  1343.      }
  1344.  
  1345.  
  1346. // Function: PaintTheIcon - processes the WM_PAINT message when iconic
  1347. // --------------------------------------------------------------------
  1348. // Parameters: HWND         hwndPicture     Handle of Picture window
  1349. //             NPMOVIEDATA  pMovieData      -> movie data struct
  1350. //
  1351. // Returns:    LONG         0L
  1352. // --------------------------------------------------------------------
  1353.    static LONG NEAR PaintTheIcon( HWND hwndMovie, NPMOVIEDATA pMovieData )
  1354.  
  1355.      {HCURSOR          hcursorSave;        // Saved cursor
  1356.       HBRUSH           hbrush;             // Temp background brush
  1357.       PicHandle        phPoster;           // Pic handle
  1358.       PAINTSTRUCT      ps;                 // Paint struct
  1359.       RECT             rcPicRect;          // Proportional pic rect
  1360.       WORD             wIconWidth;         // Icon width
  1361.       WORD             wIconHeight;        // Icon height
  1362.       WORD             wProportional;      // Temp
  1363.  
  1364.       static RECT      rcIcon =
  1365.                           {2, 2, 34, 34};  // Rect used in painting icon
  1366.  
  1367.         // Make sure the entire window rect is invalidated
  1368.       InvalidateRect( hwndMovie, NULL, FALSE );
  1369.  
  1370.       if( !BeginPaint( hwndMovie, &ps ))
  1371.           return 0L;
  1372.  
  1373.       if( !pMovieData->mMovie )
  1374.          {EndPaint( hwndMovie, &ps );
  1375.           return 0L;
  1376.          }
  1377.  
  1378.       hcursorSave = SetCursor( LoadCursor( NULL, IDC_WAIT ));
  1379.  
  1380.       if( pMovieData->bSoundOnly )
  1381.          {  // Erase the entire background since there is no picture
  1382.           if( hbrush = CreateSolidBrush( GetSysColor( COLOR_APPWORKSPACE )))
  1383.              {FillRect( ps.hdc, &ps.rcPaint, hbrush );
  1384.               DeleteObject( hbrush );
  1385.              }
  1386.                // Now draw the film strip icon
  1387.           if( g.hmovieIcon )
  1388.               DrawIcon( ps.hdc, 2, 2, g.hmovieIcon );
  1389.          }
  1390.       else
  1391.          {if( phPoster = GetMoviePosterPict( pMovieData->mMovie ))
  1392.              {rcPicRect = rcIcon;
  1393.               wIconWidth  = rcIcon.right - rcIcon.left;
  1394.               wIconHeight = rcIcon.bottom - rcIcon.top;
  1395.               if( pMovieData->idMovieInfo.width >
  1396.                                      pMovieData->idMovieInfo.height )
  1397.                  {wProportional = MulDiv( wIconHeight,
  1398.                                     pMovieData->idMovieInfo.width,
  1399.                                        pMovieData->idMovieInfo.height );
  1400.                   rcPicRect.left  -= ( wProportional - wIconWidth ) / 2;
  1401.                   rcPicRect.right = rcPicRect.left + wProportional;
  1402.                  }
  1403.               else if( pMovieData->idMovieInfo.width <
  1404.                                          pMovieData->idMovieInfo.height )
  1405.                  {wProportional = MulDiv( wIconWidth,
  1406.                                       pMovieData->idMovieInfo.height,
  1407.                                          pMovieData->idMovieInfo.width );
  1408.                   rcPicRect.top  -= ( wProportional - wIconHeight ) / 2;
  1409.                   rcPicRect.bottom = rcPicRect.top + wProportional;
  1410.                  }
  1411.  
  1412.                // Draw the poster frame
  1413.               if( DrawPicture( ps.hdc, phPoster, &rcPicRect, NULL ))
  1414.                  {CommonTellUser( PlayerQueryResources(),
  1415.                           PLAYER_STRING_DRAWPICFAILED,
  1416.                           PLAYER_STRING_CAPTION, MB_OK );
  1417.  
  1418.                     // Validate rect to prevent infinite loop
  1419.                   ValidateRect( hwndMovie, NULL );
  1420.                   DisposePicture( phPoster );
  1421.                   SetCursor( hcursorSave );
  1422.                   EndPaint( hwndMovie, &ps );
  1423.                   return 0L;
  1424.                  }
  1425.               else
  1426.                  {DisposePicture( phPoster );
  1427.                  }
  1428.              }
  1429.  
  1430.                // Now draw the film strip icon
  1431.           if( g.hmovieIcon )
  1432.               DrawIcon( ps.hdc, 2, 2, g.hmovieIcon );
  1433.  
  1434.                // Now paint background
  1435.           ExcludeClipRect( ps.hdc, rcIcon.left, rcIcon.top,
  1436.                                         rcIcon.right, rcIcon.bottom );
  1437.                // COLOR_APPWORKSPACE is standard MDI background color
  1438.           if( hbrush = CreateSolidBrush( GetSysColor( COLOR_APPWORKSPACE )))
  1439.              {FillRect( ps.hdc, &ps.rcPaint, hbrush );
  1440.               DeleteObject( hbrush );
  1441.              }
  1442.          }
  1443.  
  1444.       SetCursor( hcursorSave );
  1445.       EndPaint( hwndMovie, &ps );
  1446.  
  1447.       return 0L;
  1448.  
  1449.      }
  1450.  
  1451.  
  1452. // Function: PrintFrame - prints indicated number of copies of
  1453. //                        the selected frame at normal size
  1454. // --------------------------------------------------------------------
  1455. // Parameters: HWND         hwndMovie       Handle of movie window
  1456. //             LPPRINTDLG   lppd            -> to PRINTDLG struct created
  1457. //                                          print common dialog
  1458. //
  1459. // Returns:    LONG         0L if successful
  1460. // --------------------------------------------------------------------
  1461.    static LONG NEAR PrintFrame( HWND hwndMovie, LPPRINTDLG lppd )
  1462.  
  1463.      {NPMOVIEDATA     pMovieData;     // -> movie data struct
  1464.       WORD            i;              // Counter
  1465.       DOCINFO         diDocInfo;      // Document info struct
  1466.       PicHandle       phFrame;        // Pichandle of current frame
  1467.       BOOL            bError;         // Error flag
  1468.       int             nError;         // Error return
  1469.       OSErr           oserr;          // Error return from DrawPicture
  1470.       int             xRes;           // Horz printer resolution
  1471.       int             yRes;           // Vert printer resolution
  1472.       int             xOffset;        // Horz offset to center picture
  1473.       int             yOffset;        // Vert offset to center picture
  1474.       RECT            rcFrame;        // Frame rect
  1475.       WORD            wWidthPage;     // Width of printed page in pixels
  1476.       WORD            wHeightPage;    // Height of printed page in pixels
  1477.       TimeRecord      trMovieTime;    // Temp time record
  1478.  
  1479.  
  1480.       if( !(pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 )))
  1481.          {CommonTellUser( PlayerQueryResources(),
  1482.                   PLAYER_STRING_NOMOVIEDATA, PLAYER_STRING_CAPTION, MB_OK );
  1483.              // Turn off not reported flag
  1484.           return SP_ERROR &  ~SP_NOTREPORTED;
  1485.          }
  1486.  
  1487.       diDocInfo.cbSize      = sizeof( DOCINFO );
  1488.       diDocInfo.lpszDocName = pMovieData->szMovieName;
  1489.       diDocInfo.lpszOutput  = (LPSTR) NULL;
  1490.  
  1491.       if( !(phFrame = GetMoviePict( pMovieData->mMovie,
  1492.                          GetMovieTime( pMovieData->mMovie, &trMovieTime ))))
  1493.          {CommonTellUser( PlayerQueryResources(),
  1494.                 PLAYER_STRING_GETPICTFAILED, PLAYER_STRING_CAPTION, MB_OK );
  1495.              // Turn off not reported flag
  1496.           return SP_ERROR &  ~SP_NOTREPORTED;
  1497.          }
  1498.  
  1499.       wWidthPage  = GetDeviceCaps( lppd->hDC, HORZRES );
  1500.       wHeightPage = GetDeviceCaps( lppd->hDC, VERTRES );
  1501.  
  1502.       xRes = MulDiv( wWidthPage, 254,
  1503.                             GetDeviceCaps( lppd->hDC, HORZSIZE ) * 10 );
  1504.       yRes = MulDiv( wHeightPage, 254,
  1505.                             GetDeviceCaps( lppd->hDC, VERTSIZE ) * 10 );
  1506.       rcFrame.right  = MulDiv( pMovieData->idMovieInfo.width,
  1507.                              xRes, HIWORD( pMovieData->idMovieInfo.hRes ));
  1508.       rcFrame.bottom = MulDiv( pMovieData->idMovieInfo.height,
  1509.                              yRes, HIWORD( pMovieData->idMovieInfo.vRes ));
  1510.       rcFrame.left = rcFrame.top = 0;
  1511.  
  1512.          // Now make sure that frame fits on page
  1513.       if( rcFrame.right > (int) wWidthPage )
  1514.          {rcFrame.bottom = MulDiv( rcFrame.bottom,
  1515.                                                wWidthPage, rcFrame.right );
  1516.           rcFrame.right = wWidthPage;
  1517.          }
  1518.       if( rcFrame.bottom > (int) wHeightPage )
  1519.          {rcFrame.right = MulDiv( rcFrame.right,
  1520.                                              wHeightPage, rcFrame.bottom );
  1521.           rcFrame.bottom = wHeightPage;
  1522.          }
  1523.  
  1524.          // Now center rect on page
  1525.       xOffset = (wWidthPage  - rcFrame.right ) / 2;
  1526.       yOffset = (wHeightPage - rcFrame.bottom ) / 2;
  1527.       OffsetRect( &rcFrame, xOffset, yOffset );
  1528.  
  1529.       bError = FALSE;
  1530.       oserr  = 0L;
  1531.       nError = SP_ERROR;
  1532.  
  1533.       if( StartDoc( lppd->hDC, &diDocInfo ) > 0 )
  1534.          {for( i=0; (i < lppd->nCopies) && !bError; i++ )
  1535.              {if( StartPage( lppd->hDC ) > 0)
  1536.                  {if( (oserr = DrawPicture
  1537.                             ( lppd->hDC, phFrame, &rcFrame, NULL )) != 0L )
  1538.                      {AbortDoc( lppd->hDC );
  1539.                       bError = TRUE;
  1540.                      }
  1541.                   else if( (nError = EndPage( lppd->hDC )) < 0 )
  1542.                       bError = TRUE;
  1543.                  }
  1544.               else
  1545.                   bError = TRUE;
  1546.              }
  1547.          }
  1548.       else
  1549.           bError = TRUE;
  1550.  
  1551.       if( !bError )
  1552.           EndDoc( lppd->hDC );
  1553.  
  1554.       if( phFrame )
  1555.           DisposePicture( phFrame );
  1556.  
  1557.       return (LONG) nError;
  1558.      }
  1559.  
  1560.  
  1561. // Function: SetMinMaxInfo - Processes the WM_GETMINMAXINFO message
  1562. // --------------------------------------------------------------------
  1563. // Parameters: HWND               hwndMovie     Handle of movie wnd
  1564. //             NPMOVIEDATA        pMovieData    -> to movie data
  1565. //             MINMAXINFO FAR*    lpmmi         -> to minmaxinfo struct
  1566. //
  1567. // Returns:    LONG               always 0L
  1568. // --------------------------------------------------------------------
  1569.    static LONG NEAR SetMinMaxInfo
  1570.          ( HWND hwndMovie, NPMOVIEDATA pMovieData, MINMAXINFO FAR* lpmmi )
  1571.  
  1572.      {RECT   rcWindow;         // Movie window rect
  1573.  
  1574.       if( PlayerQueryMDIAction() == PLAYER_WINDOW_CASCADE )
  1575.          {GetWindowRect( hwndMovie, &rcWindow );
  1576.           lpmmi->ptMaxTrackSize.x = rcWindow.right - rcWindow.left;
  1577.           lpmmi->ptMaxTrackSize.y = rcWindow.bottom - rcWindow.top;
  1578.           lpmmi->ptMinTrackSize = lpmmi->ptMaxTrackSize;
  1579.           lpmmi->ptMaxSize      = lpmmi->ptMaxTrackSize;
  1580.          }
  1581.       else
  1582.          {lpmmi->ptMinTrackSize.x = 3 * GetSystemMetrics( SM_CXSIZE );
  1583.           lpmmi->ptMinTrackSize.y = GetSystemMetrics( SM_CYCAPTION ) +
  1584.                                    g.wMovieControllerHeight +
  1585.                                       2 * GetSystemMetrics( SM_CYFRAME );
  1586.              // Disable vertical resizing if sound only movie
  1587.           if( pMovieData && pMovieData->bSoundOnly )
  1588.              {lpmmi->ptMinTrackSize.y -= 2;
  1589.               lpmmi->ptMaxTrackSize.y = lpmmi->ptMinTrackSize.y;
  1590.              }
  1591.          }
  1592.  
  1593.       return 0L;
  1594.      }
  1595.  
  1596.  
  1597. // Function: GetInfoDlgProc - Get Info dialog proc
  1598. // --------------------------------------------------------------------
  1599. // Parameters: As required by Microsoft Windows
  1600. //
  1601. // Returns:    As required by Microsoft Windows
  1602. // --------------------------------------------------------------------
  1603.    BOOL __export CALLBACK GetInfoDlgProc
  1604.                 ( HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam )
  1605.  
  1606.      {NPMOVIEDATA   pMovieData;         // -> movie data struct
  1607.       HWND          hwndMovie;          // HWND of movie window
  1608.       HWND          hwndCtl;            // Handle of control
  1609.       HDC           hdc;                // DC of dialog
  1610.       int           nHeight;            // Height of control text font
  1611.  
  1612.       switch( message )
  1613.          {case WM_INITDIALOG:
  1614.              hwndMovie = (HWND) SendMessage
  1615.                     ( PlayerQueryClientWindow(), WM_MDIGETACTIVE, 0, 0L );
  1616.  
  1617.                 // Use property to associate movie window handle with
  1618.                 // info dialog. This is necessary because MDI makes frame
  1619.                 // window the parent of all dialogs no matter what handle
  1620.                 // is used in the CreateDialog call
  1621.              SetProp( hdlg, GETINFOMOVIEPROP, (HANDLE) hwndMovie );
  1622.  
  1623.              if( pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 ))
  1624.                 {pMovieData->hwndGetInfo = hdlg;
  1625.                      // Cache selection strings to speed up updates
  1626.                  if( !g.szSelectFormat[0] )
  1627.                      LoadString( PlayerQueryResources(),
  1628.                              PLAYER_STRING_SELECTION,
  1629.                                 g.szSelectFormat, sizeof( g.szSelectFormat ));
  1630.                  if( !g.szNoSelection[0] )
  1631.                      LoadString( PlayerQueryResources(),
  1632.                              PLAYER_STRING_NOSELECTION,
  1633.                                 g.szNoSelection, sizeof( g.szNoSelection ));
  1634.  
  1635.                  if( hdc = GetDC( hdlg ))
  1636.                     {nHeight = -MulDiv( 8, GetDeviceCaps( hdc, LOGPIXELSY ), 72 );
  1637.                      if( pMovieData->hfInfo = MakeAnArialFont( hdc, nHeight ))
  1638.                         {hwndCtl = GetWindow( hdlg, GW_CHILD );
  1639.                          while( hwndCtl )
  1640.                             {if( GetDlgCtrlID( hwndCtl ) != IDOK )
  1641.                                 SendMessage( hwndCtl, WM_SETFONT,
  1642.                                                  (WPARAM) pMovieData->hfInfo, 0 );
  1643.                              hwndCtl = GetWindow( hwndCtl, GW_HWNDNEXT );
  1644.                             }
  1645.                         }
  1646.                      ReleaseDC( hdlg, hdc );
  1647.                     }
  1648.  
  1649.                  FillMovieInfo( hdlg, pMovieData );
  1650.                 }
  1651.  
  1652.              return TRUE;
  1653.  
  1654.          case WM_ACTIVATE:
  1655.              PlayerSetActiveModeless( wParam, hdlg );
  1656.              return TRUE;
  1657.  
  1658. // WM_USER messages
  1659.  
  1660.           case WM_PLAYER_INFO_UPDATEFILENAME:
  1661.              hwndMovie = (HWND) GetProp( hdlg, GETINFOMOVIEPROP );
  1662.              if( IsWindow( hwndMovie ) && ( pMovieData =
  1663.                         (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 )))
  1664.                  UpdateInfoFileName( pMovieData );
  1665.              break;
  1666.  
  1667.           case WM_PLAYER_INFO_UPDATE:
  1668.              hwndMovie = (HWND) GetProp( hdlg, GETINFOMOVIEPROP );
  1669.              if( IsWindow( hwndMovie ) && ( pMovieData =
  1670.                         (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 )))
  1671.                  FillMovieInfo( hdlg, pMovieData );
  1672.              break;
  1673.  
  1674. // End WM_USER messages
  1675.  
  1676.           case WM_COMMAND:
  1677.              return DestroyWindow( hdlg );
  1678.  
  1679.           case WM_DESTROY:
  1680.              hwndMovie = (HWND) GetProp( hdlg, GETINFOMOVIEPROP );
  1681.              if( IsWindow( hwndMovie ) && ( pMovieData =
  1682.                                (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 )))
  1683.                 {pMovieData->hwndGetInfo = NULL;
  1684.  
  1685.                  if( pMovieData->hfInfo )
  1686.                      DeleteObject( pMovieData->hfInfo );
  1687.                  pMovieData->hfInfo = NULL;
  1688.                 }
  1689.  
  1690.              RemoveProp( hdlg, GETINFOMOVIEPROP );
  1691.              break;
  1692.          }
  1693.  
  1694.       return FALSE;
  1695.  
  1696.      }
  1697.  
  1698.  
  1699. // Function: FillMovieInfo - Fills dialog controls with movie data
  1700. // --------------------------------------------------------------------
  1701. // Parameters: HWND          hdlg            Handle of dialog wnd
  1702. //             NPMOVIEDATA   pMovieData      -> movie data struct
  1703. //
  1704. // Returns:    VOID
  1705. // --------------------------------------------------------------------
  1706.    static VOID NEAR FillMovieInfo( HWND hdlg, NPMOVIEDATA pMovieData )
  1707.  
  1708.      {char           szBuffer[MAX_PATH_LEN];       // Buffer
  1709.       char           szFormat[30];                 // Format buffer
  1710.       TimeValue      tvDuration;                   // Duration of movie
  1711.       double         fTimeScale;                   // Timescale
  1712.       RECT           rcMovie;                      // Current movie rect
  1713.       DWORD          dwColors;                     // Number of colors
  1714.       char           szCompressor[sizeof(DWORD) + 1];  // compressor type
  1715.       WORD           wIDString;                    // Colors string id
  1716.       DWORD          dwRate;                       // Sound sample rate
  1717.       DWORD          dwKRate;                      // Sound sample rate
  1718.       char           szNull[] = "";                // Static null string
  1719.  
  1720.       g.bUpdatingInfo = TRUE;
  1721.  
  1722.    // Movie name: Append duplication index if > 0
  1723.       UpdateInfoFileName( pMovieData );
  1724.  
  1725.    // file size
  1726.       SetDlgItemText( hdlg, MOVIE_INFO_FILESIZE, pMovieData->szFileSize );
  1727.  
  1728.          // Get movie time scale
  1729.       if( ( fTimeScale = (double)
  1730.                     GetMovieTimeScale( pMovieData->mMovie )) != 0. )
  1731.          {   // Do these only if timescale != zero to avoid divide by 0
  1732.              // Movie duration
  1733.           tvDuration = GetMovieDuration( pMovieData->mMovie );
  1734.           LoadString( PlayerQueryResources(), PLAYER_STRING_DURATION,
  1735.                                            szFormat, sizeof( szFormat ));
  1736.           sprintf( szBuffer, szFormat, tvDuration / fTimeScale );
  1737.           SetDlgItemText( hdlg, MOVIE_INFO_DURATION, szBuffer );
  1738.  
  1739.              // Current selection
  1740.           DisplayCurrentSelection( pMovieData );
  1741.          }
  1742.  
  1743.       if( !pMovieData->bSoundOnly )
  1744.          { // Current size
  1745.           LoadString( PlayerQueryResources(), PLAYER_STRING_WANDH,
  1746.                                              szFormat, sizeof( szFormat ));
  1747.           GetMovieBox( pMovieData->mMovie, &rcMovie );
  1748.  
  1749.           wsprintf( szBuffer, szFormat, rcMovie.right - rcMovie.left,
  1750.                                           rcMovie.bottom - rcMovie.top );
  1751.           SetDlgItemText( hdlg, MOVIE_INFO_CURSIZE, szBuffer );
  1752.  
  1753.            // Normal Width and Height
  1754.           wsprintf( szBuffer, szFormat,
  1755.                               pMovieData->idMovieInfo.width,
  1756.                                      pMovieData->idMovieInfo.height );
  1757.           SetDlgItemText( hdlg, MOVIE_INFO_WANDH, szBuffer );
  1758.           wsprintf( szBuffer, szFormat, pMovieData->idMovieInfo.height );
  1759.  
  1760.            // Resolution
  1761.           if( HIWORD( pMovieData->idMovieInfo.hRes ) != 0 )
  1762.              {LoadString( PlayerQueryResources(),
  1763.                       PLAYER_STRING_RESOLUTION, szFormat, sizeof( szFormat ));
  1764.               wsprintf( szBuffer, szFormat,
  1765.                                     HIWORD( pMovieData->idMovieInfo.hRes ));
  1766.              }
  1767.           else
  1768.              {LoadString( PlayerQueryResources(),
  1769.                       PLAYER_STRING_NORESOLUTION, szBuffer, sizeof( szBuffer ));
  1770.              }
  1771.           SetDlgItemText( hdlg, MOVIE_INFO_RESOLUTION, szBuffer );
  1772.  
  1773.  
  1774.            // Normal colors
  1775.           switch( pMovieData->idMovieInfo.depth )
  1776.              {case 1:        // Black and White
  1777.                   wIDString = PLAYER_STRING_CLRS_BANDW;      break;
  1778.               case 1 + 32:   // 2 Grays
  1779.                   wIDString = PLAYER_STRING_CLRS_2GRAYS;     break;
  1780.               case 2:        // 4 Colors
  1781.                   wIDString = PLAYER_STRING_CLRS_4COLORS;    break;
  1782.               case 2 + 32:   // 4 Grays
  1783.                   wIDString = PLAYER_STRING_CLRS_4GRAYS;     break;
  1784.               case 4:        // 16 Colors
  1785.                   wIDString = PLAYER_STRING_CLRS_16COLORS;   break;
  1786.               case 4 + 32:   // 16 Grays
  1787.                   wIDString = PLAYER_STRING_CLRS_16GRAYS;    break;
  1788.               case 8:        // 256 Colors
  1789.                   wIDString = PLAYER_STRING_CLRS_256COLORS;  break;
  1790.               case 8 + 32:   // 256 Grays
  1791.                   wIDString = PLAYER_STRING_CLRS_256GRAYS;   break;
  1792.               case 16:       // Thousands of Colors
  1793.                   wIDString = PLAYER_STRING_CLRS_THOUSANDS;  break;
  1794.               case 24:       // Millions of Colors
  1795.                   wIDString = PLAYER_STRING_CLRS_MILLIONS;   break;
  1796.               case 32:       // Millions of Colors+
  1797.                   wIDString = PLAYER_STRING_CLRS_MILLNSPLUS; break;
  1798.               default:
  1799.                   wIDString = 0xffff;
  1800.                   if( pMovieData->idMovieInfo.depth < 32 )
  1801.                      {LoadString( PlayerQueryResources(), PLAYER_STRING_COLORS,
  1802.                                              szFormat, sizeof( szFormat ));
  1803.                       dwColors = 1L << pMovieData->idMovieInfo.depth;
  1804.                       wsprintf( szBuffer, szFormat, dwColors );
  1805.                      }
  1806.                   else
  1807.                      {szBuffer[0] = '\0';
  1808.                      }
  1809.                   break;
  1810.              }
  1811.           if( wIDString != 0xffff )
  1812.               LoadString( PlayerQueryResources(), wIDString,
  1813.                                              szBuffer, sizeof( szBuffer ));
  1814.           SetDlgItemText( hdlg, MOVIE_INFO_COLORS, szBuffer );
  1815.  
  1816.            // Compressor type. Use .name if not empty
  1817.           if( pMovieData->idMovieInfo.name[0] )
  1818.              {SetDlgItemText( hdlg, MOVIE_INFO_COMPRESSOR,
  1819.                                               pMovieData->idMovieInfo.name );
  1820.              }
  1821.           else  // Check Codec type for 'raw'
  1822.              {  // Compressor type is stored as a DWORD. i.e. 'jpeg'
  1823.                 // Spaces in "raw ", "rle " etc are necessary !!!
  1824.               if( pMovieData->idMovieInfo.CodecType )
  1825.                  {*((PDWORD) &szCompressor) = pMovieData->idMovieInfo.CodecType;
  1826.                   szCompressor[ sizeof(DWORD) ] = '\0';
  1827.                  }
  1828.               szBuffer[0] = '\0';
  1829.               if( !pMovieData->idMovieInfo.CodecType ||
  1830.                                 !lstrcmpi( szCompressor, "raw " ))
  1831.                   wIDString = PLAYER_STRING_CODEC_NONE;
  1832.               else if( !lstrcmpi( szCompressor, "jpeg" ))
  1833.                   wIDString = PLAYER_STRING_CODEC_PHOTO;
  1834.               else if( !lstrcmpi( szCompressor, "rle " ))
  1835.                   wIDString = PLAYER_STRING_CODEC_ANIMATION;
  1836.               else if( !lstrcmpi( szCompressor, "smc " ))
  1837.                   wIDString = PLAYER_STRING_CODEC_GRAPHICS;
  1838.               else if( !lstrcmpi( szCompressor, "rpza" ))
  1839.                   wIDString = PLAYER_STRING_CODEC_VIDEO;
  1840.               else if( !lstrcmpi( szCompressor, "cvid" ))
  1841.                   wIDString = PLAYER_STRING_CODEC_CVID;
  1842.               else
  1843.                   wIDString = PLAYER_STRING_CODEC_NONE;
  1844.  
  1845.               LoadString( PlayerQueryResources(), wIDString,
  1846.                                                szBuffer, sizeof( szBuffer ));
  1847.  
  1848.               SetDlgItemText( hdlg, MOVIE_INFO_COMPRESSOR, szBuffer );
  1849.              }
  1850.          }
  1851.       else
  1852.          {LoadString( PlayerQueryResources(),
  1853.                       PLAYER_STRING_NOVIDEO, szBuffer, sizeof( szBuffer ));
  1854.           SetDlgItemText( hdlg, MOVIE_INFO_CURSIZE,    szBuffer );
  1855.           SetDlgItemText( hdlg, MOVIE_INFO_WANDH,      szNull );
  1856.           SetDlgItemText( hdlg, MOVIE_INFO_RESOLUTION, szNull );
  1857.           SetDlgItemText( hdlg, MOVIE_INFO_COLORS,     szNull );
  1858.           SetDlgItemText( hdlg, MOVIE_INFO_COMPRESSOR, szNull );
  1859.          }
  1860.  
  1861.   // Sound info
  1862.       if( pMovieData->oserrSoundInfo == noSoundTrackInMovie )
  1863.          {LoadString( PlayerQueryResources(),
  1864.                    PLAYER_STRING_SND_NOSOUND, szBuffer, sizeof( szBuffer ));
  1865.           SetDlgItemText( hdlg, MOVIE_INFO_SND_NUMCHANNELS, szBuffer );
  1866.           SetDlgItemText( hdlg, MOVIE_INFO_SND_SOUNDQUALITY, szNull );
  1867.          }
  1868.       else if( pMovieData->oserrSoundInfo == soundSupportNotAvailable )
  1869.          {LoadString( PlayerQueryResources(),
  1870.                    PLAYER_STRING_SND_NOCARD, szBuffer, sizeof( szBuffer ));
  1871.           SetDlgItemText( hdlg, MOVIE_INFO_SND_NUMCHANNELS, szBuffer );
  1872.           SetDlgItemText( hdlg, MOVIE_INFO_SND_SOUNDQUALITY, szNull );
  1873.          }
  1874.       else if( pMovieData->oserrSoundInfo )
  1875.          {  // GetSoundInfo call failed so doen't write anything
  1876.          }
  1877.       else
  1878.          { // Num of channels
  1879.           if( pMovieData->sdSoundInfo.numChannels == 1 )
  1880.               LoadString( PlayerQueryResources(), PLAYER_STRING_SND_MONO,
  1881.                                              szBuffer, sizeof( szBuffer ));
  1882.           else
  1883.               LoadString( PlayerQueryResources(), PLAYER_STRING_SND_STEREO,
  1884.                                              szBuffer, sizeof( szBuffer ));
  1885.           SetDlgItemText( hdlg, MOVIE_INFO_SND_NUMCHANNELS, szBuffer );
  1886.  
  1887.            // Sample size and rate
  1888.           LoadString( PlayerQueryResources(),
  1889.                PLAYER_STRING_SND_SOUNDQUALITY, szFormat, sizeof( szFormat ));
  1890.           dwRate = ((DWORD) pMovieData->sdSoundInfo.sampleRate ) / 65536L;
  1891.           dwKRate = dwRate / 1000;
  1892.           dwRate -= dwKRate * 1000;
  1893.           wsprintf( szBuffer, szFormat,
  1894.                          pMovieData->sdSoundInfo.sampleSize, dwKRate, dwRate );
  1895.           SetDlgItemText( hdlg, MOVIE_INFO_SND_SOUNDQUALITY, szBuffer );
  1896.          }
  1897.  
  1898.   // End sound info
  1899.  
  1900.       g.bUpdatingInfo = FALSE;
  1901.  
  1902.       return;
  1903.      }
  1904.  
  1905.  
  1906. // Function: UpdateInfoFileName - Updates the file name with the current
  1907. //                                instance count in the info dialog
  1908. // --------------------- -----------------------------------------------
  1909. // Parameters: NPMOVIEDATA    pMovieData       -> to MOVIEDATA struct
  1910. //
  1911. // Returns:    VOID
  1912. // --------------------------------------------------------------------
  1913.    static VOID NEAR UpdateInfoFileName( NPMOVIEDATA pMovieData )
  1914.  
  1915.      {char      szBuffer[MAX_NAME_LEN + 10];  // Buffer
  1916.       char      szFormat[20];                 // Format buffer
  1917.  
  1918.       lstrcpy( szFormat, "%s%s" );
  1919.       if( pMovieData->wDuplicationIndex > 0 )
  1920.           lstrcat( szFormat, ":%u" );
  1921.       wsprintf( szBuffer, szFormat, (LPSTR) pMovieData->szMovieName,
  1922.                         (LPSTR) pMovieData->szMovieExt,
  1923.                                  pMovieData->wDuplicationIndex );
  1924.       AnsiUpper( szBuffer );
  1925.       SetDlgItemText( pMovieData-> hwndGetInfo,
  1926.                                MOVIE_INFO_NAME, (LPSTR) szBuffer );
  1927.  
  1928.       return;
  1929.      }
  1930.  
  1931.  
  1932. // Function:  DisplayCurrentSelection - Displays the current selection in
  1933. //                                      the info dialog
  1934. // --------------------------------------------------------------------
  1935. // Parameters: NPMOVIEDATA      pMovieData        -> movie data struct
  1936. //
  1937. // Returns:    VOID
  1938. // --------------------------------------------------------------------
  1939.    static VOID NEAR DisplayCurrentSelection( NPMOVIEDATA pMovieData )
  1940.  
  1941.      {char     szBuffer[100];           // Buffer
  1942.       double   fSelectionStart;         // Beginning of selection
  1943.       double   fSelectionEnd;           // End of selection
  1944.       double   fTimeScale;              // Time scale of movie
  1945.  
  1946.       if( ( ( fTimeScale = (double)
  1947.                    GetMovieTimeScale( pMovieData->mMovie )) != 0. ) &&
  1948.               ( pMovieData->trSelectionStart.value.dwLo != (DWORD) -1) &&
  1949.                        ( pMovieData->trSelectionDuration.value.dwLo > 0L ))
  1950.          {fSelectionStart = pMovieData->trSelectionStart.value.dwLo /
  1951.                                                                fTimeScale ;
  1952.           fSelectionEnd = fSelectionStart +
  1953.                         pMovieData->trSelectionDuration.value.dwLo /
  1954.                                                                fTimeScale ;
  1955.  
  1956.           sprintf( szBuffer, g.szSelectFormat, fSelectionStart, fSelectionEnd );
  1957.           SetDlgItemText( pMovieData-> hwndGetInfo,
  1958.                                            MOVIE_INFO_SELECTION, szBuffer );
  1959.          }
  1960.       else
  1961.          {SetDlgItemText( pMovieData-> hwndGetInfo,
  1962.                                     MOVIE_INFO_SELECTION, g.szNoSelection );
  1963.          }
  1964.  
  1965.       return;
  1966.  
  1967.      }
  1968.  
  1969.  
  1970. // Function: ActionFilter - Used to filter the selection change message
  1971. // --------------------------------------------------------------------
  1972. // Parameters: MovieController  mcController      Movie controller
  1973. //             UNIT             psAction          action parameter
  1974. //             LPVOID           lpParm            DoAction parameter
  1975. //             LONG             lUserData         User defined data
  1976. //
  1977. // Returns:    BOOL             TRUE  if no further action
  1978. //                              FALSE if controller is to perform action
  1979. // --------------------------------------------------------------------
  1980.    BOOL __export CALLBACK ActionFilter
  1981.                ( MovieController mcController, UINT psAction,
  1982.                                          LPVOID lpParm, LONG lUserData )
  1983.  
  1984.      {NPMOVIEDATA         pMovieData;       // -> movie data struct
  1985.  
  1986.       switch( psAction )
  1987.          {case mcActionControllerSizeChanged:
  1988.               pMovieData = (NPMOVIEDATA) LOWORD( lUserData );
  1989.               if( !pMovieData->bSettingControllerSize )
  1990.                  {ResizeMovieAndWindow( (HWND) HIWORD( lUserData ),
  1991.                                                    FALSE, pMovieData, 0, 0 );
  1992.                   if( pMovieData->hwndGetInfo && !g.bUpdatingInfo )
  1993.                      { // Need to post message here because FALSE second
  1994.                        // parameter prevents ResizeMovie from being called
  1995.                        // by ResizeMovieAndWindow.
  1996.                        // WM_PLAYER_INFO_UPDATE is defined to be in
  1997.                        // the range WM_COALESCE_FIRST to WM_COALESCE_LAST
  1998.                        // which tells Windows to prevent duplicate messages
  1999.                        // from appearing in the queue.
  2000.                       PostMessage( pMovieData->hwndGetInfo,
  2001.                                           WM_PLAYER_INFO_UPDATE, 0, 0L );
  2002.                      }
  2003.                  }
  2004.               else
  2005.                  {pMovieData->bSettingControllerSize = FALSE;
  2006.                  }
  2007.  
  2008.               break;
  2009.  
  2010.           case mcActionSetSelectionBegin:
  2011.               pMovieData = (NPMOVIEDATA) LOWORD( lUserData );
  2012.               pMovieData->trSelectionStart = *( TimeRecord FAR *) lpParm;
  2013.  
  2014.               break;
  2015.  
  2016.           case mcActionSetSelectionDuration:
  2017.               pMovieData = (NPMOVIEDATA) LOWORD( lUserData );
  2018.               pMovieData->trSelectionDuration = *( TimeRecord FAR *) lpParm;
  2019.  
  2020.               if( pMovieData->hwndGetInfo )
  2021.                   DisplayCurrentSelection( pMovieData );
  2022.               break;
  2023.  
  2024.           default:
  2025.               break;
  2026.          }
  2027.  
  2028.       return FALSE;
  2029.      }
  2030.  
  2031.  
  2032. // Function: InitializePopupMenus - Called just before the popup menus
  2033. //                                  are displayed
  2034. // --------------------------------------------------------------------
  2035. // Parameters: HWND         hwndMovie       Handle of movie window
  2036. //             HMENU        hmenuPopup      Handle of popup menu
  2037. //             int          nPopupIndex     Index of popup
  2038. //
  2039. // Returns:    LONG         0L if successful
  2040. // --------------------------------------------------------------------
  2041.    static LONG NEAR InitializePopupMenus
  2042.                    ( HWND hwndMovie, HMENU hmenuPopup, int nPopupIndex )
  2043.  
  2044.      {NPMOVIEDATA   pMovieData;           // -> movie data struct
  2045.       LONG          lControllerInfo;      // Controller info
  2046.       BOOL          bLooping;             // TRUE if looping
  2047.       BOOL          bPalindrome;          // TRUE if looping palindrome
  2048.       BOOL          bPlaySelectionOnly;   // TRUE if playing selection only
  2049.       WORD          wSelectedSize;        // Nonzero if movie is a standard size
  2050.       RECT          rcMovie;              // Movie rect
  2051.       WORD          wMovieWidth;          // Width of movie
  2052.       WORD          wMovieHeight;         // Height of movie
  2053.       char          szTitle[64];          // OLE Client doc title
  2054.       char          szItemFormat1[32];    // Item format string
  2055.       char          szItem1[128];         // New item string
  2056.       char          szItemFormat2[32];    // Item format string
  2057.       char          szItem2[128];         // New item string
  2058.  
  2059.  
  2060.  
  2061.       if( !(pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 )))
  2062.          {CommonTellUser( PlayerQueryResources(),
  2063.                   PLAYER_STRING_NOMOVIEDATA, PLAYER_STRING_CAPTION, MB_OK );
  2064.           return 0L;
  2065.          }
  2066.  
  2067.       MCGetControllerInfo( pMovieData->mcMovieController,
  2068.                                                        &lControllerInfo );
  2069.  
  2070.          // Decrement index if maximized since MDI adds a system menu item
  2071.          // which puts count off by one
  2072.       if( IsZoomed( hwndMovie ))
  2073.           nPopupIndex--;
  2074.  
  2075.       if( nPopupIndex == MENU_FILE_POS )
  2076.          {   // See if wnd is an activated client object
  2077.           if( QTOLE_IsActiveObjectWnd
  2078.                          ( PlayerQueryOleData(), hwndMovie, szTitle ))
  2079.              {LoadString( PlayerQueryResources(),
  2080.                     PLAYER_STRING_OLECLOSE, szItemFormat1, sizeof( szItemFormat1 ));
  2081.               wsprintf( szItem1, szItemFormat1, (LPSTR) szTitle );
  2082.  
  2083.               LoadString( PlayerQueryResources(),
  2084.                     PLAYER_STRING_OLEEXIT, szItemFormat2, sizeof( szItemFormat2 ));
  2085.               wsprintf( szItem2, szItemFormat2, (LPSTR) szTitle );
  2086.              }
  2087.           else
  2088.              {LoadString( PlayerQueryResources(),
  2089.                          PLAYER_STRING_CLOSE, szItem1, sizeof( szItem1 ));
  2090.               LoadString( PlayerQueryResources(),
  2091.                          PLAYER_STRING_EXIT, szItem2, sizeof( szItem2 ));
  2092.              }
  2093.  
  2094.           DeleteMenu( hmenuPopup, PLAYER_FILE_CLOSE, MF_BYCOMMAND );
  2095.           InsertMenu( hmenuPopup, 1, MF_BYPOSITION,
  2096.                                              PLAYER_FILE_CLOSE, szItem1 );
  2097.           DeleteMenu( hmenuPopup, PLAYER_FILE_EXIT, MF_BYCOMMAND );
  2098.           InsertMenu( hmenuPopup, (UINT) -1, MF_BYPOSITION,
  2099.                                              PLAYER_FILE_EXIT, szItem2 );
  2100.  
  2101.           EnableMenuItem( hmenuPopup, PLAYER_FILE_PRINT,
  2102.              ( pMovieData->bSoundOnly ||
  2103.              (lControllerInfo & mcInfoIsPlaying)) ? MF_GRAYED: MF_ENABLED );
  2104.           EnableMenuItem( hmenuPopup, PLAYER_FILE_PRTSETUP,
  2105.                           pMovieData->bSoundOnly ? MF_GRAYED: MF_ENABLED );
  2106.          }
  2107.       else if( nPopupIndex == MENU_EDIT_POS )
  2108.          {EnableMenuItem( hmenuPopup, PLAYER_EDIT_COPY,
  2109.             ( IsIconic( hwndMovie ) ||
  2110.              ( lControllerInfo & mcInfoIsPlaying )) ? MF_GRAYED: MF_ENABLED );
  2111.           EnableMenuItem( hmenuPopup, PLAYER_EDIT_OPTIONS,
  2112.             ( IsIconic( hwndMovie ) ||
  2113.              ( lControllerInfo & mcInfoIsPlaying )) ? MF_GRAYED: MF_ENABLED );
  2114.  
  2115.          }
  2116.       else if( nPopupIndex == MENU_MOVIE_POS )
  2117.          {bLooping    = (( lControllerInfo & mcInfoIsLooping ) != 0L );
  2118.           bPalindrome = (( lControllerInfo & mcInfoIsInPalindrome ) != 0L );
  2119.  
  2120.           CheckMenuItem( hmenuPopup, PLAYER_MOVIE_STOPATEND,
  2121.                   ( bLooping || bPalindrome ) ? MF_UNCHECKED: MF_CHECKED );
  2122.           CheckMenuItem( hmenuPopup, PLAYER_MOVIE_LOOP,
  2123.                  ( bLooping && !bPalindrome ) ? MF_CHECKED: MF_UNCHECKED );
  2124.           CheckMenuItem( hmenuPopup, PLAYER_MOVIE_BACKANDFORTH,
  2125.                   ( bLooping && bPalindrome ) ? MF_CHECKED: MF_UNCHECKED );
  2126.  
  2127.               // Toggle play selection only
  2128.           MCDoAction( pMovieData->mcMovieController,
  2129.                    mcActionGetPlaySelection, (LPVOID) &bPlaySelectionOnly );
  2130.           CheckMenuItem( hmenuPopup, PLAYER_MOVIE_PLAYSELONLY,
  2131.                        ( bPlaySelectionOnly ) ? MF_CHECKED: MF_UNCHECKED );
  2132.  
  2133.  
  2134.           EnableMenuItem( hmenuPopup, PLAYER_MOVIE_HALFSIZE,
  2135.                           pMovieData->bSoundOnly ? MF_GRAYED: MF_ENABLED );
  2136.           EnableMenuItem( hmenuPopup, PLAYER_MOVIE_NORMALSIZE,
  2137.                           pMovieData->bSoundOnly ? MF_GRAYED: MF_ENABLED );
  2138.           EnableMenuItem( hmenuPopup, PLAYER_MOVIE_DOUBLESIZE,
  2139.                           pMovieData->bSoundOnly ? MF_GRAYED: MF_ENABLED );
  2140.  
  2141.               // Set selected size parameter if movie is a standard size
  2142.           if( IsIconic( hwndMovie ))
  2143.               wSelectedSize = 0;
  2144.           else
  2145.              {GetMovieBox( pMovieData->mMovie, &rcMovie );
  2146.               wMovieWidth  = rcMovie.right - rcMovie.left;
  2147.               wMovieHeight = rcMovie.bottom - rcMovie.top;
  2148.  
  2149.               if( ( wMovieWidth == pMovieData->idMovieInfo.width ) &&
  2150.                        ( wMovieHeight == pMovieData->idMovieInfo.height ))
  2151.                   wSelectedSize = PLAYER_MOVIE_NORMALSIZE;
  2152.               else if( ( wMovieWidth == pMovieData->idMovieInfo.width * 2 ) &&
  2153.                     ( wMovieHeight == pMovieData->idMovieInfo.height * 2 ))
  2154.                   wSelectedSize = PLAYER_MOVIE_DOUBLESIZE;
  2155.               else if( ( wMovieWidth == pMovieData->idMovieInfo.width / 2 ) &&
  2156.                     ( wMovieHeight == pMovieData->idMovieInfo.height / 2 ))
  2157.                   wSelectedSize = PLAYER_MOVIE_HALFSIZE;
  2158.               else
  2159.                   wSelectedSize = 0;
  2160.              }
  2161.  
  2162.           CheckMenuItem( hmenuPopup, PLAYER_MOVIE_HALFSIZE,
  2163.                  ( !pMovieData->bSoundOnly &&
  2164.                   ( wSelectedSize == PLAYER_MOVIE_HALFSIZE)) ?
  2165.                                                 MF_CHECKED: MF_UNCHECKED );
  2166.           CheckMenuItem( hmenuPopup, PLAYER_MOVIE_NORMALSIZE,
  2167.                  ( !pMovieData->bSoundOnly &&
  2168.                   ( wSelectedSize == PLAYER_MOVIE_NORMALSIZE)) ?
  2169.                                                 MF_CHECKED: MF_UNCHECKED );
  2170.           CheckMenuItem( hmenuPopup, PLAYER_MOVIE_DOUBLESIZE,
  2171.                  ( !pMovieData->bSoundOnly &&
  2172.                   ( wSelectedSize == PLAYER_MOVIE_DOUBLESIZE)) ?
  2173.                                                 MF_CHECKED: MF_UNCHECKED );
  2174.  
  2175.           EnableMenuItem( hmenuPopup, PLAYER_MOVIE_SHOWPOSTER,
  2176.                           pMovieData->bSoundOnly ? MF_GRAYED: MF_ENABLED );
  2177.          }
  2178.  
  2179.       return 0L;
  2180.      }
  2181.  
  2182.  
  2183. // Function: ResizeMovieAndWindow - Resizes the movie and window to the
  2184. //                                  input width and height if flag is TRUE
  2185. //                                  Otherwise resize window to match movie
  2186. // --------------------------------------------------------------------
  2187. // Parameters: HWND         hwndMovie       Handle of Movie window
  2188. //             BOOL         bResizeMovie    TRUE if movie should be resized
  2189. //                                          This will be FALSE when the grow
  2190. //                                          box is used to resize since the
  2191. //                                          movie will already be resized
  2192. //             NPMOVIEDATA  pMovieData      -> to movie data struct
  2193. //             WORD         wMovieWidth     width of movie
  2194. //             WORD         wMovieHeight    height of movie
  2195. //
  2196. // Returns:    LONG         0L if successful
  2197. // --------------------------------------------------------------------
  2198.    static LONG NEAR ResizeMovieAndWindow( HWND hwndMovie, BOOL bResizeMovie,
  2199.                   NPMOVIEDATA pMovieData, WORD wMovieWidth, WORD wMovieHeight )
  2200.  
  2201.      {RECT          rcWindow;       // Window rect
  2202.       RECT          rcWindowPrev;   // Prev Window rect
  2203.       RECT          rcBounds;       // Bounds rect
  2204.       POINT         ptCorner;       // Upper-Left corner of window
  2205.       LONG          lError;         // Error return
  2206.       POINT         ptTemp[2];      // Temp array of points
  2207.  
  2208.  
  2209.       if( bResizeMovie &&
  2210.           ( lError = ResizeMovie( pMovieData, wMovieWidth, wMovieHeight )))
  2211.           return lError;
  2212.  
  2213.          // Now Get the bounds rect. In this app, this is the same as the
  2214.          // client rect of the window
  2215.       MCGetControllerBoundsRect( pMovieData->mcMovieController, &rcBounds );
  2216.  
  2217.          // Set about resizing window
  2218.          // Save the prev window rect in client window coordinates
  2219.       GetWindowRect( hwndMovie, &rcWindow );
  2220.       MapWindowPoints( HWND_DESKTOP, PlayerQueryClientWindow(),
  2221.                                             (LPPOINT) &rcWindow, 2 );
  2222.       rcWindowPrev = rcWindow;
  2223.       ptCorner = *((LPPOINT) &rcWindow );
  2224.  
  2225.          // Adjust corner. This will only happen if window has been
  2226.          // moved using the grow box
  2227.       if( !bResizeMovie && ( rcBounds.left || rcBounds.top ))
  2228.          {ptTemp[0].x = ptTemp[0].y = 0;
  2229.           ptTemp[1] = *((LPPOINT) &rcBounds );
  2230.           MapWindowPoints( hwndMovie, PlayerQueryClientWindow(), ptTemp, 2 );
  2231.  
  2232.           ptCorner.x += ptTemp[1].x - ptTemp[0].x;
  2233.           ptCorner.y += ptTemp[1].y - ptTemp[0].y;
  2234.          }
  2235.  
  2236.       rcWindow = rcBounds;
  2237.       AdjustWindowRect( &rcWindow,
  2238.                       GetWindowLong( hwndMovie, GWL_STYLE ), FALSE );
  2239.          // rcWindow contains the new size of the window.
  2240.          // Now offset to the corrent UL corner
  2241.       OffsetRect( &rcWindow, ptCorner.x - rcWindow.left,
  2242.                                           ptCorner.y - rcWindow.top );
  2243.  
  2244.          // If window rect has changed, resize after
  2245.          // disabling the WM_SIZE processing
  2246.       if( !EqualRect( &rcWindow, &rcWindowPrev ))
  2247.          {pMovieData->bDisableSizeMsgProcessing = TRUE;
  2248.           MoveWindow( hwndMovie, rcWindow.left, rcWindow.top,
  2249.                                rcWindow.right - rcWindow.left,
  2250.                                   rcWindow.bottom - rcWindow.top, TRUE );
  2251.  
  2252.          // If if happens that after resizing, the movie is smaller than
  2253.          // minimum movie window size, resize movie to fill the window
  2254.           GetClientRect( hwndMovie, &rcWindow );
  2255.           if( !EqualRect( &rcWindow, &rcBounds ))
  2256.              {pMovieData->bSettingControllerSize = TRUE;
  2257.               MCSetControllerBoundsRect
  2258.                           ( pMovieData->mcMovieController, &rcWindow );
  2259.              }
  2260.          }
  2261.  
  2262.       return 0L;
  2263.      }
  2264.  
  2265.  
  2266. // Function: ResizeMovie - Resizes the movie to the given size
  2267. // --------------------------------------------------------------------
  2268. // Parameters: NPMOVIEDATA  pMovieData      Pointer to movie data struct
  2269. //             WORD         wMovieWidth     width of movie
  2270. //             WORD         wMovieHeight    height of movie
  2271. //
  2272. // Returns:    LONG         0L if successful
  2273. // --------------------------------------------------------------------
  2274.    static LONG NEAR ResizeMovie( NPMOVIEDATA pMovieData,
  2275.                                     WORD wMovieWidth, WORD wMovieHeight )
  2276.  
  2277.      {RECT     rcBounds;        // Controller bounds rect
  2278.  
  2279.          // set based on input movie dimensions.
  2280.          // Need to add in controller height for bounds rect
  2281.       rcBounds.left = rcBounds.top = 0;
  2282.       rcBounds.right  = wMovieWidth;
  2283.       rcBounds.bottom = wMovieHeight + g.wMovieControllerHeight;
  2284.  
  2285.       pMovieData->bSettingControllerSize = TRUE;
  2286.       MCSetControllerBoundsRect( pMovieData->mcMovieController, &rcBounds );
  2287.  
  2288.       if( pMovieData->hwndGetInfo && !g.bUpdatingInfo )
  2289.          { // WM_PLAYER_INFO_UPDATE is defined to be in the range WM_COALESCE_FIRST
  2290.            // to WM_COALESCE_LAST which tells Windows to prevent duplicate messages
  2291.            // from appearing in the queue.
  2292.           PostMessage( pMovieData->hwndGetInfo, WM_PLAYER_INFO_UPDATE, 0, 0L );
  2293.          }
  2294.  
  2295.       return 0L;
  2296.      }
  2297.  
  2298.  
  2299. // Function: UpdateGBBoundsRect - Updates the grow box bounds rect
  2300. // --------------------------------------------------------------------
  2301. // Parameters: HWND            hwndMovie     Handle of movie window
  2302. //             NPMOVIEDATA     pMovieData    -> movie data struct
  2303. //
  2304. // Returns:    VOID
  2305. // --------------------------------------------------------------------
  2306.    static VOID NEAR UpdateGBBoundsRect( HWND hwndMovie, NPMOVIEDATA pMovieData )
  2307.  
  2308.      {GetClientRect( PlayerQueryFrameWindow(), &pMovieData->rcGrowBox );
  2309.       MapWindowPoints( PlayerQueryFrameWindow(),
  2310.                          hwndMovie, (LPPOINT) &pMovieData->rcGrowBox , 2 );
  2311.       MCDoAction( pMovieData->mcMovieController,
  2312.                         mcActionSetGrowBoxBounds, &pMovieData->rcGrowBox );
  2313.  
  2314.       return;
  2315.  
  2316.      }
  2317.  
  2318.  
  2319. // Function: MakeAnArialFont - Creates a logical font
  2320. // --------------------------------------------------------------------
  2321. // Parameters: HDC           hdc              Device context
  2322. //             int           nTextSize        Size of font
  2323. //
  2324. // Returns:    HFONT         hFont
  2325. //           Note: It is up to the caller to eventually delete this font
  2326. // --------------------------------------------------------------------
  2327.    static HFONT NEAR MakeAnArialFont( HDC hdc, int nTextSize )
  2328.  
  2329.      {HFONT       hFont;         // Handle to created font
  2330.       PLOGFONT    plf;           // -> to font struct
  2331.  
  2332.       if( !(plf = (PLOGFONT) LocalAlloc( LPTR, sizeof( LOGFONT ))))
  2333.           return NULL;
  2334.  
  2335.       plf->lfHeight         = nTextSize;
  2336.       plf->lfWeight         = FW_LIGHT;
  2337.       plf->lfOutPrecision   = OUT_TT_ONLY_PRECIS;
  2338.       plf->lfPitchAndFamily = FF_SWISS;
  2339.       LoadString( PlayerQueryResources(), PLAYER_STRING_FACENAME,
  2340.                            plf->lfFaceName, sizeof( plf->lfFaceName ));
  2341.  
  2342.       hFont = CreateFontIndirect( plf );
  2343.  
  2344.       LocalFree( (LOCALHANDLE) plf );
  2345.  
  2346.       return hFont;
  2347.      }
  2348.  
  2349.  
  2350. // Function: InitializeResize - Tests for constrained resize and
  2351. //                              sets dragging rect if true
  2352. // --------------------------------------------------------------------
  2353. // Parameters: HWND          hwndMovie        Handle of movie wnd
  2354. //             NPMOVIEDATA   pMovieData       -> movie data struct
  2355. //             WORD          wHitTestCode     NC hit test code
  2356. //             POINT         ptCursor         Position of cursor in
  2357. //                                            screen coordinates
  2358. //
  2359. // Returns:    WORD          wHitTestCode if in border, else 0
  2360. // --------------------------------------------------------------------
  2361.    static WORD NEAR InitializeResize
  2362.              ( HWND hwndMovie, NPMOVIEDATA pMovieData,
  2363.                                    WORD wHitTestCode, POINT ptCursor )
  2364.  
  2365.      {RECT        rcClipCursor;       // Rect used to clip motion of cursor
  2366.       MINMAXINFO  mmiMinMaxInfo;      // Minmax info struct
  2367.  
  2368.  
  2369.       GetWindowRect( hwndMovie, &g.rcResizeRect );
  2370.       GetWindowRect( PlayerQueryClientWindow(), &rcClipCursor );
  2371.  
  2372.       SetMinMaxInfo( hwndMovie, pMovieData, &mmiMinMaxInfo );
  2373.  
  2374.       switch( wHitTestCode )
  2375.          {case HTTOP:
  2376.               g.ptCursorOffset.x = 0;
  2377.               g.ptCursorOffset.y = g.rcResizeRect.top - ptCursor.y;
  2378.  
  2379.               rcClipCursor.bottom = g.rcResizeRect.bottom -
  2380.                                    mmiMinMaxInfo.ptMinTrackSize.y;
  2381.               break;
  2382.           case HTBOTTOM:
  2383.               g.ptCursorOffset.x = 0;
  2384.               g.ptCursorOffset.y = g.rcResizeRect.bottom - ptCursor.y;
  2385.  
  2386.               rcClipCursor.top = g.rcResizeRect.top +
  2387.                                    mmiMinMaxInfo.ptMinTrackSize.y;
  2388.               break;
  2389.           case HTLEFT:
  2390.               g.ptCursorOffset.x = g.rcResizeRect.left - ptCursor.x;
  2391.               g.ptCursorOffset.y = 0;
  2392.  
  2393.               rcClipCursor.right = g.rcResizeRect.right -
  2394.                                    mmiMinMaxInfo.ptMinTrackSize.x;
  2395.               break;
  2396.           case HTRIGHT:
  2397.               g.ptCursorOffset.x = g.rcResizeRect.right - ptCursor.x;
  2398.               g.ptCursorOffset.y = 0;
  2399.  
  2400.               rcClipCursor.left = g.rcResizeRect.left +
  2401.                                    mmiMinMaxInfo.ptMinTrackSize.x;
  2402.               break;
  2403.           case HTTOPLEFT:
  2404.               g.ptCursorOffset.x = g.rcResizeRect.left - ptCursor.x;
  2405.               g.ptCursorOffset.y = g.rcResizeRect.top - ptCursor.y;
  2406.  
  2407.               rcClipCursor.right  = g.rcResizeRect.right -
  2408.                                    mmiMinMaxInfo.ptMinTrackSize.x;
  2409.               if( !pMovieData->bSoundOnly )
  2410.                   rcClipCursor.bottom = g.rcResizeRect.bottom -
  2411.                                    mmiMinMaxInfo.ptMinTrackSize.y;
  2412.               break;
  2413.           case HTBOTTOMRIGHT:
  2414.               g.ptCursorOffset.x = g.rcResizeRect.right - ptCursor.x;
  2415.               g.ptCursorOffset.y = g.rcResizeRect.bottom - ptCursor.y;
  2416.  
  2417.               rcClipCursor.left = g.rcResizeRect.left +
  2418.                                    mmiMinMaxInfo.ptMinTrackSize.x;
  2419.               if( !pMovieData->bSoundOnly )
  2420.                   rcClipCursor.top  = g.rcResizeRect.top +
  2421.                                    mmiMinMaxInfo.ptMinTrackSize.y;
  2422.               break;
  2423.           case HTTOPRIGHT:
  2424.               g.ptCursorOffset.x = g.rcResizeRect.right - ptCursor.x;
  2425.               g.ptCursorOffset.y = g.rcResizeRect.top - ptCursor.y;
  2426.  
  2427.               rcClipCursor.left   = g.rcResizeRect.left +
  2428.                                    mmiMinMaxInfo.ptMinTrackSize.x;
  2429.               if( !pMovieData->bSoundOnly )
  2430.                   rcClipCursor.bottom = g.rcResizeRect.bottom -
  2431.                                    mmiMinMaxInfo.ptMinTrackSize.y;
  2432.               break;
  2433.           case HTBOTTOMLEFT:
  2434.               g.ptCursorOffset.x = g.rcResizeRect.left - ptCursor.x;
  2435.               g.ptCursorOffset.y = g.rcResizeRect.bottom - ptCursor.y;
  2436.  
  2437.               rcClipCursor.right = g.rcResizeRect.right -
  2438.                                    mmiMinMaxInfo.ptMinTrackSize.x;
  2439.               if( !pMovieData->bSoundOnly )
  2440.                   rcClipCursor.top   = g.rcResizeRect.top +
  2441.                                    mmiMinMaxInfo.ptMinTrackSize.y;
  2442.               break;
  2443.  
  2444.           default:
  2445.               return 0;
  2446.          }
  2447.  
  2448.  
  2449.       if( pMovieData->bSoundOnly )
  2450.          {SetCursor( g.hcursor = LoadCursor( NULL, IDC_SIZEWE ));
  2451.          }
  2452.       else
  2453.          {SetCursor( g.hcursor = SetCursor( NULL ));
  2454.          }
  2455.       ClipCursor( &rcClipCursor );
  2456.  
  2457.       g.wScaleWidth  = max( pMovieData->idMovieInfo.width / 2, 1 );
  2458.       g.wScaleHeight = max( pMovieData->idMovieInfo.height / 2, 1 );
  2459.  
  2460.       return wHitTestCode;
  2461.      }
  2462.  
  2463.  
  2464. // Function: MoveTheMovieResizeRect - Moves the resizing frame
  2465. // --------------------------------------------------------------------
  2466. // Parameters: HWND          hwndMovie       Handle of movie window
  2467. //             NPMOVIEDATA   pMovieData      -> movie data struct
  2468. //             WORD          wHitTestCode    Hit test code
  2469. //             POINT         ptCursor        Current cursor position in
  2470. //                                           screen coordinates
  2471. //             BOOL          bStarting       TRUE if this is the first
  2472. //                                           call of a drag
  2473. //
  2474. // Returns:    VOID
  2475. // --------------------------------------------------------------------
  2476.    static VOID NEAR MoveTheMovieResizeRect
  2477.             ( HWND hwndMovie, NPMOVIEDATA pMovieData,
  2478.                    WORD wHitTestCode, POINT ptCursor, BOOL bStarting )
  2479.  
  2480.      {RECT     rcNewRect;        // resize rect in screen coordinates
  2481.       WORD     wMovieWidth;      // Movie width
  2482.       WORD     wMovieHeight;     // Movie height
  2483.  
  2484.       ptCursor.x += g.ptCursorOffset.x;
  2485.       ptCursor.y += g.ptCursorOffset.y;
  2486.  
  2487.       rcNewRect = g.rcResizeRect;
  2488.       switch( wHitTestCode )
  2489.          {case HTTOP:
  2490.               if( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT ))
  2491.                  {rcNewRect.top = ptCursor.y;
  2492.                  }
  2493.               else
  2494.                  {wMovieHeight = rcNewRect.bottom - ptCursor.y -
  2495.                                                          g.wTopAndBottom;
  2496.                   if( ISKEYDOWN( VK_CONTROL ))
  2497.                      {wMovieHeight = g.wScaleHeight *
  2498.                                    max( wMovieHeight / g.wScaleHeight, 1 );
  2499.  
  2500.                       if( abs( wMovieHeight -
  2501.                                  pMovieData->idMovieInfo.height ) <= 2 )
  2502.                          {wMovieWidth  = pMovieData->idMovieInfo.width;
  2503.                           wMovieHeight = pMovieData->idMovieInfo.height;
  2504.                          }
  2505.                       else
  2506.                          {wMovieWidth = MulDiv( wMovieHeight,
  2507.                                     pMovieData->idMovieInfo.width,
  2508.                                            pMovieData->idMovieInfo.height );
  2509.                          }
  2510.                      }
  2511.                   else
  2512.                      {wMovieWidth = MulDiv( wMovieHeight,
  2513.                                     pMovieData->idMovieInfo.width,
  2514.                                            pMovieData->idMovieInfo.height );
  2515.                      }
  2516.  
  2517.                   rcNewRect.right = rcNewRect.left + g.wSides + wMovieWidth;
  2518.                   rcNewRect.top   = rcNewRect.bottom -
  2519.                                             g.wTopAndBottom - wMovieHeight;
  2520.                  }
  2521.               break;
  2522.           case HTBOTTOM:
  2523.               if( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT ))
  2524.                  {rcNewRect.bottom = ptCursor.y;
  2525.                  }
  2526.               else
  2527.                  {wMovieHeight = ptCursor.y - rcNewRect.top - g.wTopAndBottom;
  2528.                   if( ISKEYDOWN( VK_CONTROL ))
  2529.                      {wMovieHeight = g.wScaleHeight *
  2530.                                    max( wMovieHeight / g.wScaleHeight, 1 );
  2531.                       if( abs( wMovieHeight -
  2532.                                  pMovieData->idMovieInfo.height ) <= 2 )
  2533.                          {wMovieWidth  = pMovieData->idMovieInfo.width;
  2534.                           wMovieHeight = pMovieData->idMovieInfo.height;
  2535.                          }
  2536.                       else
  2537.                          {wMovieWidth = MulDiv( wMovieHeight,
  2538.                                     pMovieData->idMovieInfo.width,
  2539.                                            pMovieData->idMovieInfo.height );
  2540.                          }
  2541.                      }
  2542.                   else
  2543.                      {wMovieWidth = MulDiv( wMovieHeight,
  2544.                                     pMovieData->idMovieInfo.width,
  2545.                                            pMovieData->idMovieInfo.height );
  2546.                      }
  2547.  
  2548.                   rcNewRect.right  = rcNewRect.left + g.wSides + wMovieWidth;
  2549.                   rcNewRect.bottom = rcNewRect.top +
  2550.                                             g.wTopAndBottom + wMovieHeight;
  2551.                  }
  2552.               break;
  2553.           case HTLEFT:
  2554.               if( pMovieData->bSoundOnly ||
  2555.                     ( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT )))
  2556.                  {rcNewRect.left = ptCursor.x;
  2557.                  }
  2558.               else
  2559.                  {wMovieWidth = rcNewRect.right - ptCursor.x - g.wSides;
  2560.                   if( ISKEYDOWN( VK_CONTROL ))
  2561.                      {wMovieWidth = g.wScaleWidth *
  2562.                                    max( wMovieWidth / g.wScaleWidth, 1 );
  2563.                       if( abs( wMovieWidth -
  2564.                                  pMovieData->idMovieInfo.width ) <= 2 )
  2565.                          {wMovieWidth  = pMovieData->idMovieInfo.width;
  2566.                           wMovieHeight = pMovieData->idMovieInfo.height;
  2567.                          }
  2568.                       else
  2569.                          {wMovieHeight = MulDiv( wMovieWidth,
  2570.                                     pMovieData->idMovieInfo.height,
  2571.                                            pMovieData->idMovieInfo.width );
  2572.                          }
  2573.                      }
  2574.                   else
  2575.                      {wMovieHeight = MulDiv( wMovieWidth,
  2576.                                     pMovieData->idMovieInfo.height,
  2577.                                            pMovieData->idMovieInfo.width );
  2578.                      }
  2579.  
  2580.                   rcNewRect.left   = rcNewRect.right - g.wSides - wMovieWidth;
  2581.                   rcNewRect.bottom = rcNewRect.top +
  2582.                                              g.wTopAndBottom + wMovieHeight;
  2583.                  }
  2584.               break;
  2585.           case HTRIGHT:
  2586.               if( pMovieData->bSoundOnly ||
  2587.                     ( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT )))
  2588.                  {rcNewRect.right = ptCursor.x;
  2589.                  }
  2590.               else
  2591.                  {wMovieWidth = ptCursor.x - rcNewRect.left - g.wSides;
  2592.                   if( ISKEYDOWN( VK_CONTROL ))
  2593.                      {wMovieWidth = g.wScaleWidth *
  2594.                                    max( wMovieWidth / g.wScaleWidth, 1 );
  2595.                       if( abs( wMovieWidth -
  2596.                                  pMovieData->idMovieInfo.width ) <= 2 )
  2597.                          {wMovieWidth  = pMovieData->idMovieInfo.width;
  2598.                           wMovieHeight = pMovieData->idMovieInfo.height;
  2599.                          }
  2600.                       else
  2601.                          {wMovieHeight = MulDiv( wMovieWidth,
  2602.                                     pMovieData->idMovieInfo.height,
  2603.                                            pMovieData->idMovieInfo.width );
  2604.                          }
  2605.                      }
  2606.                   else
  2607.                      {wMovieHeight = MulDiv( wMovieWidth,
  2608.                                     pMovieData->idMovieInfo.height,
  2609.                                            pMovieData->idMovieInfo.width );
  2610.                      }
  2611.  
  2612.                   rcNewRect.right  = rcNewRect.left + g.wSides + wMovieWidth;
  2613.                   rcNewRect.bottom = rcNewRect.top +
  2614.                                            g.wTopAndBottom + wMovieHeight;
  2615.                  }
  2616.               break;
  2617.           case HTTOPLEFT:
  2618.               if( pMovieData->bSoundOnly )
  2619.                  {rcNewRect.left = ptCursor.x;
  2620.                  }
  2621.               else if( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT ))
  2622.                  {*((LPPOINT) &rcNewRect.left) = ptCursor;
  2623.                  }
  2624.               else
  2625.                  {wMovieWidth  = rcNewRect.right - ptCursor.x - g.wSides;
  2626.                   wMovieHeight = rcNewRect.bottom - ptCursor.y -
  2627.                                                        g.wTopAndBottom;
  2628.                   GetProportionalDimensions( pMovieData,
  2629.                           &wMovieWidth, &wMovieHeight, ISKEYDOWN( VK_CONTROL ));
  2630.                   rcNewRect.top = rcNewRect.bottom - wMovieHeight -
  2631.                                                            g.wTopAndBottom;
  2632.                   rcNewRect.left = rcNewRect.right - wMovieWidth - g.wSides;
  2633.                  }
  2634.               break;
  2635.           case HTBOTTOMRIGHT:
  2636.               if( pMovieData->bSoundOnly )
  2637.                  {rcNewRect.right = ptCursor.x;
  2638.                  }
  2639.               else if( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT ))
  2640.                  {*((LPPOINT) &rcNewRect.right) = ptCursor;
  2641.                  }
  2642.               else
  2643.                  {wMovieWidth  = ptCursor.x - rcNewRect.left - g.wSides;
  2644.                   wMovieHeight = ptCursor.y - rcNewRect.top - g.wTopAndBottom;
  2645.                   GetProportionalDimensions( pMovieData,
  2646.                           &wMovieWidth, &wMovieHeight, ISKEYDOWN( VK_CONTROL ));
  2647.                   rcNewRect.bottom = rcNewRect.top + wMovieHeight +
  2648.                                                            g.wTopAndBottom;
  2649.                   rcNewRect.right = rcNewRect.left + wMovieWidth + g.wSides;
  2650.                  }
  2651.               break;
  2652.           case HTTOPRIGHT:
  2653.               if( pMovieData->bSoundOnly )
  2654.                  {rcNewRect.right = ptCursor.x;
  2655.                  }
  2656.               else if( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT ))
  2657.                  {rcNewRect.right = ptCursor.x;
  2658.                   rcNewRect.top   = ptCursor.y;
  2659.                  }
  2660.               else
  2661.                  {wMovieWidth  = ptCursor.x - rcNewRect.left - g.wSides;
  2662.                   wMovieHeight = rcNewRect.bottom -
  2663.                                             ptCursor.y - g.wTopAndBottom;
  2664.                   GetProportionalDimensions( pMovieData,
  2665.                           &wMovieWidth, &wMovieHeight, ISKEYDOWN( VK_CONTROL ));
  2666.                   rcNewRect.top = rcNewRect.bottom - wMovieHeight -
  2667.                                                            g.wTopAndBottom;
  2668.                   rcNewRect.right = rcNewRect.left + wMovieWidth + g.wSides;
  2669.                  }
  2670.               break;
  2671.           case HTBOTTOMLEFT:
  2672.               if( pMovieData->bSoundOnly )
  2673.                  {rcNewRect.left = ptCursor.x;
  2674.                  }
  2675.               else if( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT ))
  2676.                  {rcNewRect.left   = ptCursor.x;
  2677.                   rcNewRect.bottom = ptCursor.y;
  2678.                  }
  2679.               else
  2680.                  {wMovieWidth  = rcNewRect.right - ptCursor.x - g.wSides;
  2681.                   wMovieHeight = ptCursor.y - rcNewRect.top - g.wTopAndBottom;
  2682.                   GetProportionalDimensions( pMovieData,
  2683.                           &wMovieWidth, &wMovieHeight, ISKEYDOWN( VK_CONTROL ));
  2684.                   rcNewRect.bottom = rcNewRect.top + wMovieHeight +
  2685.                                                            g.wTopAndBottom;
  2686.                   rcNewRect.left = rcNewRect.right - wMovieWidth - g.wSides;
  2687.                  }
  2688.               break;
  2689.          }
  2690.  
  2691.       if( bStarting )
  2692.          {g.rcResizeRect = rcNewRect;
  2693.           g.bFatResizeBorder = IsNormalSize( &g.rcResizeRect, pMovieData );
  2694.           DrawTheFrameRect( &g.rcResizeRect, g.bFatResizeBorder );
  2695.          }
  2696.       else if( !EqualRect( &g.rcResizeRect, &rcNewRect ))
  2697.          {DrawTheFrameRect( &g.rcResizeRect, g.bFatResizeBorder );
  2698.           g.rcResizeRect = rcNewRect;
  2699.           g.bFatResizeBorder = IsNormalSize( &g.rcResizeRect, pMovieData );
  2700.           DrawTheFrameRect( &g.rcResizeRect, g.bFatResizeBorder );
  2701.          }
  2702.  
  2703.       return;
  2704.      }
  2705.  
  2706.  
  2707. // Function: AdjustForMinProportionalSize - Adjusts the final dimensions of a movie
  2708. //                                          when a dimension is less than a minimum
  2709. //                                          allowed size
  2710. // --------------------------------------------------------------------
  2711. // Parameters: HWND             hwndMovie      Handle of movie wnd
  2712. //             NPMOVIEDATA      pMovieData     -> movie data struct
  2713. //             LPWORD           lpwWidth;      -> window width
  2714. //             LPWORD           lpwHeight;     -> window height
  2715. //             BOOL             bCtrlKeyDown   TRUE if CONTROL key is down
  2716. //
  2717. // Returns:    VOID
  2718. // --------------------------------------------------------------------
  2719.    static VOID NEAR AdjustForMinProportionalSize
  2720.              ( HWND hwndMovie, NPMOVIEDATA pMovieData,
  2721.                     LPWORD lpwWidth, LPWORD lpwHeight, BOOL bCtrlKeyDown )
  2722.  
  2723.      {MINMAXINFO  mmiMinMaxInfo;      // Minmax info struct
  2724.       WORD        wMovieWidth;        // Movie width
  2725.       WORD        wMovieHeight;       // Movie height
  2726.  
  2727.  
  2728.       SetMinMaxInfo( hwndMovie, pMovieData, &mmiMinMaxInfo );
  2729.            // Add resizing borders
  2730.       mmiMinMaxInfo.ptMinTrackSize.x += g.wSides;
  2731.       mmiMinMaxInfo.ptMinTrackSize.y += g.wTBBorder;
  2732.  
  2733.       if( ( *lpwWidth > (WORD) mmiMinMaxInfo.ptMinTrackSize.x ) &&
  2734.                    ( *lpwHeight > (WORD) mmiMinMaxInfo.ptMinTrackSize.y ))
  2735.           return;
  2736.  
  2737.       if( *lpwWidth < (WORD) mmiMinMaxInfo.ptMinTrackSize.x )
  2738.          {*lpwWidth = mmiMinMaxInfo.ptMinTrackSize.x;
  2739.          }
  2740.       if( *lpwHeight < (WORD) mmiMinMaxInfo.ptMinTrackSize.y )
  2741.          {*lpwHeight = mmiMinMaxInfo.ptMinTrackSize.y;
  2742.          }
  2743.  
  2744.            // Mult by 10 because numbers may be small
  2745.       wMovieWidth  = ( *lpwWidth - g.wSides ) * 10;
  2746.       wMovieHeight = ( *lpwHeight - g.wTopAndBottom ) * 10;
  2747.       GetProportionalDimensions
  2748.              ( pMovieData, &wMovieWidth, &wMovieHeight, bCtrlKeyDown );
  2749.       *lpwWidth  = ( wMovieWidth + 10 * g.wSides ) / 10;
  2750.       *lpwHeight = ( wMovieHeight + 10 * g.wTopAndBottom ) / 10;
  2751.  
  2752.       return;
  2753.  
  2754.      }
  2755.  
  2756.  
  2757. // Function: GetProportionalDimensions - Scales the dimensions of a movie to
  2758. //                                       be in the same proportions as the
  2759. //                                       original movie dimensions
  2760. // --------------------------------------------------------------------
  2761. // Parameters: NPMOVIEDATA    pMovieData        -> movie data struct
  2762. //             PWORD          pwMovieWidth      -> current width
  2763. //             PWORD          pwMovieHeight     -> current height
  2764. //             BOOL           bCtrlKeyDown      TRUE if CONTROL key is down
  2765. //
  2766. // Returns:    VOID
  2767. // --------------------------------------------------------------------
  2768.    static VOID NEAR GetProportionalDimensions
  2769.          ( NPMOVIEDATA pMovieData, PWORD pwMovieWidth,
  2770.                                    PWORD pwMovieHeight, BOOL bCtrlKeyDown )
  2771.  
  2772.      {WORD     wTempHeight;     // Temp height
  2773.  
  2774.       wTempHeight = MulDiv( *pwMovieWidth,
  2775.                             pMovieData->idMovieInfo.height,
  2776.                                    pMovieData->idMovieInfo.width );
  2777.       if( wTempHeight >= *pwMovieHeight )
  2778.          {*pwMovieHeight = wTempHeight;
  2779.          }
  2780.       else
  2781.          {*pwMovieWidth = MulDiv( *pwMovieHeight,
  2782.                          pMovieData->idMovieInfo.width,
  2783.                                  pMovieData->idMovieInfo.height );
  2784.          }
  2785.  
  2786.       if( bCtrlKeyDown )
  2787.          {*pwMovieHeight = g.wScaleHeight *
  2788.                               max( *pwMovieHeight / g.wScaleHeight, 1 );
  2789.  
  2790.           if( abs( *pwMovieHeight - pMovieData->idMovieInfo.height ) <= 2 )
  2791.              {*pwMovieWidth  = pMovieData->idMovieInfo.width;
  2792.               *pwMovieHeight = pMovieData->idMovieInfo.height;
  2793.              }
  2794.           else
  2795.              {*pwMovieWidth = MulDiv( *pwMovieHeight,
  2796.                                     pMovieData->idMovieInfo.width,
  2797.                                            pMovieData->idMovieInfo.height );
  2798.              }
  2799.          }
  2800.  
  2801.       return;
  2802.      }
  2803.  
  2804.  
  2805. // Function: IsNormalSize - Determines if movie is normal size
  2806. // --------------------------------------------------------------------
  2807. // Parameters: RECT          lprcResizeRect   -> resize rect
  2808. //             NPMOVIEDATA   pMovieData       -> movie data struct
  2809. //
  2810. // Returns:    BOOL     TRUE if input rect has the normal movie dimensions
  2811. // --------------------------------------------------------------------
  2812.    static BOOL NEAR IsNormalSize
  2813.                       ( LPRECT lprcResizeRect, NPMOVIEDATA pMovieData )
  2814.  
  2815.      {WORD    wMovieWidth;          // Current width of movie
  2816.       WORD    wMovieHeight;         // Current height of movie
  2817.  
  2818.       wMovieWidth = lprcResizeRect->right -
  2819.                                     lprcResizeRect->left - g.wSides;
  2820.       wMovieHeight = lprcResizeRect->bottom -
  2821.                                lprcResizeRect->top - g.wTopAndBottom;
  2822.  
  2823.       return ( wMovieWidth == pMovieData->idMovieInfo.width ) &&
  2824.                 ( wMovieHeight == pMovieData->idMovieInfo.height );
  2825.      }
  2826.  
  2827.  
  2828. // Function: DrawTheFrameRect - Draws the resizing frame
  2829. // --------------------------------------------------------------------
  2830. // Parameters: RECT      lprcResizeRect     -> resize rect
  2831. //             BOOL      bFatBorder         Flag to draw thicker border
  2832. //
  2833. // Returns:    VOID
  2834. // --------------------------------------------------------------------
  2835.    static VOID NEAR DrawTheFrameRect( LPRECT lprcResizeRect, BOOL bFatBorder )
  2836.  
  2837.      {HDC            hdc;               // DC of desktop
  2838.       HBRUSH         hbrushSave;        // Prev brush
  2839.       HBITMAP        hbitmapCheckers;   // Handle of checkerboard bitmap
  2840.       WORD           wWBorder;          // Width of vertical border
  2841.       WORD           wHBorder;          // Width of horizontal border
  2842.  
  2843.  
  2844.    typedef  BOOL ( CALLBACK* FFRAMEPROC ) (HDC, LPRECT, int, int, DWORD);
  2845.  
  2846.       static  WORD   wBorderWidth;      // Width of vertical resize border
  2847.       static  WORD   wBorderHeight;     // Height of horizontal resize border
  2848.       static  FFRAMEPROC  lpfnFastWindowFrame;   // -> FastWindowFrame()
  2849.       static  HBRUSH  hbrushCheckers;   // Handle to frame brush
  2850.  
  2851.          // FastWindowFrame() is an undocumented Windows function
  2852.          // described in "Undocumented Windows" by Andrew Schulman,
  2853.          // David Maxey and Matt Pietrek, Addison Wesley, 1992.
  2854.  
  2855.       if( lprcResizeRect == NULL )    // Clean up
  2856.          {if( hbrushCheckers )
  2857.              {DeleteObject( hbrushCheckers );
  2858.               hbrushCheckers = NULL;
  2859.              }
  2860.           return;
  2861.          }
  2862.  
  2863.       if( !lpfnFastWindowFrame )
  2864.          {lpfnFastWindowFrame = (FFRAMEPROC) GetProcAddress(
  2865.                             GetModuleHandle( "GDI" ), "FASTWINDOWFRAME" );
  2866.           wBorderWidth  = GetSystemMetrics( SM_CXFRAME ) - 1;
  2867.           wBorderHeight = GetSystemMetrics( SM_CXFRAME ) - 1;
  2868.          }
  2869.  
  2870.       if( !hbrushCheckers &&
  2871.            ( hbitmapCheckers = LoadBitmap( PlayerQueryInstance(),
  2872.                            MAKEINTRESOURCE( PLAYER_CHECKERS_BITMAP ))))
  2873.          {hbrushCheckers = CreatePatternBrush( hbitmapCheckers );
  2874.           DeleteObject( hbitmapCheckers );
  2875.          }
  2876.  
  2877.       if( hdc = GetDC( NULL ))
  2878.          {if( lpfnFastWindowFrame )
  2879.              {if( hbrushCheckers )
  2880.                   hbrushSave = SelectObject( hdc, hbrushCheckers );
  2881.               else
  2882.                   hbrushSave = SelectObject( hdc,
  2883.                                          GetStockObject( GRAY_BRUSH ));
  2884.  
  2885.               wWBorder = wBorderWidth  + ( bFatBorder? 2: 0);
  2886.               wHBorder = wBorderHeight + ( bFatBorder? 2: 0);
  2887.  
  2888.               if( !( *lpfnFastWindowFrame ) ( hdc, lprcResizeRect,
  2889.                                       wWBorder, wHBorder, PATINVERT ))
  2890.                  { // Use PatBlt when FastWindowFrame fails
  2891.                   ExcludeClipRect( hdc,
  2892.                                 lprcResizeRect->left + wWBorder,
  2893.                                 lprcResizeRect->top  + wHBorder,
  2894.                                 lprcResizeRect->right  - wWBorder,
  2895.                                 lprcResizeRect->bottom - wHBorder );
  2896.  
  2897.                   PatBlt( hdc, lprcResizeRect->left,
  2898.                                lprcResizeRect->top,
  2899.                                lprcResizeRect->right - lprcResizeRect->left,
  2900.                                lprcResizeRect->bottom - lprcResizeRect->top,
  2901.                                PATINVERT );
  2902.                  }
  2903.  
  2904.               if( hbrushSave )
  2905.                   SelectObject( hdc, hbrushSave );
  2906.              }
  2907.           else
  2908.              {DrawFocusRect( hdc, lprcResizeRect );
  2909.              }
  2910.  
  2911.           ReleaseDC( NULL, hdc );
  2912.          }
  2913.  
  2914.       return;
  2915.      }
  2916.  
  2917.  
  2918. // Function: SubclassTheGrowBox - Subclass the movie controller grow box
  2919. // --------------------------------------------------------------------
  2920. // Parameters: HWND           hwndMovie    Handle of movie wnd
  2921. //             NPMOVIEDATA    pMovieData   -> movie data struct
  2922. //
  2923. // Returns:    BOOL    TRUE if successful
  2924. // --------------------------------------------------------------------
  2925.    static BOOL NEAR SubclassTheGrowBox
  2926.                                  ( HWND hwndMovie, NPMOVIEDATA pMovieData )
  2927.  
  2928.      {WNDENUMPROC     lpfnEnumProc;     // -> enumeration proc
  2929.  
  2930.       if( lpfnEnumProc = (WNDENUMPROC) MakeProcInstance
  2931.                 ( (FARPROC) MovieChildEnumProc, PlayerQueryInstance()))
  2932.          {EnumChildWindows( hwndMovie, lpfnEnumProc,
  2933.                                             MAKELONG( pMovieData, 0 ));
  2934.           FreeProcInstance( (FARPROC) lpfnEnumProc );
  2935.  
  2936.           return pMovieData->bGrowBoxSubclassed;
  2937.          }
  2938.  
  2939.       return FALSE;
  2940.      }
  2941.  
  2942.  
  2943. // Function: MovieChildEnumProc - Movie child enumeration proc
  2944. // --------------------------------------------------------------------
  2945. // Parameters: As required by Microsoft Windows
  2946. //
  2947. // Returns:    As required by Microsoft Windows
  2948. // --------------------------------------------------------------------
  2949.    BOOL __export CALLBACK MovieChildEnumProc
  2950.                                  ( HWND hwndChild, LPARAM lParam )
  2951.  
  2952.      {char      szClassName[50];        // Class name buffer
  2953.  
  2954.           // The grow box class name can be found by using the enumeration
  2955.           // routine to list all the names
  2956.    #define GROWBOXCLASSNAME   "MCGrowBox"
  2957.  
  2958.       if( GetClassName( hwndChild,
  2959.                    szClassName, sizeof( szClassName )) &&
  2960.                          !lstrcmpi( GROWBOXCLASSNAME, szClassName ))
  2961.          {if( g.lpNewGBProc ||
  2962.                 ( g.lpNewGBProc = (WNDPROC) MakeProcInstance
  2963.                   ( (FARPROC) GBSubClassProc, PlayerQueryInstance())))
  2964.              {if( g.lpOldGBProc = (WNDPROC) SetWindowLong
  2965.                       ( hwndChild, GWL_WNDPROC, (LONG) g.lpNewGBProc ))
  2966.                  {((NPMOVIEDATA) LOWORD( lParam ))->
  2967.                                              bGrowBoxSubclassed = TRUE;
  2968.                  }
  2969.              }
  2970.  
  2971.           return FALSE;
  2972.          }
  2973.  
  2974.       return TRUE;
  2975.      }
  2976.  
  2977.  
  2978. // Function: GBSubClassProc - Movie controller grow box subclass
  2979. // --------------------------------------------------------------------
  2980. // Parameters: As required by Microsoft Windows
  2981. //
  2982. // Returns:    As required by Microsoft Windows
  2983. // --------------------------------------------------------------------
  2984.    LONG __export CALLBACK GBSubClassProc
  2985.            ( HWND hwndGrowBox, UINT message, WPARAM wParam, LPARAM lParam )
  2986.  
  2987.      {POINT    ptCursor;      // Cursor position
  2988.  
  2989.       if( g.hwndMaximizedMovie && ( message == WM_LBUTTONDOWN ))
  2990.          {ptCursor = MAKEPOINT( lParam );
  2991.           ClientToScreen( hwndGrowBox, &ptCursor );
  2992.           InitMaxWndGrowBoxResize( hwndGrowBox, ptCursor );
  2993.  
  2994.           SetCapture( g.hwndMaximizedMovie );
  2995.           g.bCapturedGrowBox = TRUE;
  2996.  
  2997.           return 0L;
  2998.          }
  2999.  
  3000.       return CallWindowProc
  3001.                    ( g.lpOldGBProc, hwndGrowBox, message, wParam, lParam );
  3002.      }
  3003.  
  3004.  
  3005. // Function: InitMaxWndGrowBoxResize - Initializes the maximized window grow
  3006. //                                     box resizing
  3007. // --------------------------------------------------------------------
  3008. // Parameters: HWND        hwndGrowBox    Handle of grow box
  3009. //             POINT       ptCursor       Position of cursor in screen coords.
  3010. //
  3011. // Returns:    BOOL        TRUE if successful
  3012. // --------------------------------------------------------------------
  3013.    static BOOL NEAR InitMaxWndGrowBoxResize
  3014.                                  ( HWND hwndGrowBox, POINT ptCursor )
  3015.  
  3016.      {RECT         rcClipCursor;      // Clip cursor rect
  3017.       HDC          hdc;               // DC of desktop
  3018.  
  3019.       GetWindowRect( PlayerQueryFrameWindow(), &g.rcResizeRect );
  3020.       g.ptCursorOffset.x = g.rcResizeRect.right  - ptCursor.x;
  3021.       g.ptCursorOffset.y = g.rcResizeRect.bottom - ptCursor.y;
  3022.  
  3023.       rcClipCursor.left = g.rcResizeRect.left +
  3024.                GetSystemMetrics( SM_CXMINTRACK ) - g.ptCursorOffset.x;
  3025.       rcClipCursor.top  = g.rcResizeRect.top +
  3026.                GetSystemMetrics( SM_CYMINTRACK ) - g.ptCursorOffset.y;
  3027.  
  3028.           // Offset the clip cursor rect to keep frame on screen
  3029.       if( hdc = GetDC( NULL ))
  3030.          {rcClipCursor.right =
  3031.                   GetDeviceCaps( hdc, HORZRES ) - g.ptCursorOffset.x;
  3032.           rcClipCursor.bottom =
  3033.                   GetDeviceCaps( hdc, VERTRES ) - g.ptCursorOffset.y;
  3034.           ReleaseDC( NULL, hdc );
  3035.          }
  3036.        else
  3037.          {rcClipCursor.right  = 0x7fff;
  3038.           rcClipCursor.bottom = 0x7fff;
  3039.          }
  3040.       ClipCursor( &rcClipCursor );
  3041.  
  3042.       DrawTheFrameRect( &g.rcResizeRect, FALSE );
  3043.  
  3044.       return TRUE;
  3045.      }
  3046.  
  3047.  
  3048. // Function: MoveTheFrameResizeRect - Moves the resizing frame during
  3049. //                                    maximized wnd grow box resizing
  3050. // --------------------------------------------------------------------
  3051. // Parameters: HWND          hwndMovie     Handle of movie wnd
  3052. //             POINT         ptCursor      Current cursor position in
  3053. //                                         screen coordinates
  3054. //
  3055. // Returns:    VOID
  3056. // --------------------------------------------------------------------
  3057.    static VOID NEAR MoveTheFrameResizeRect
  3058.                              ( HWND hwndMovie, POINT ptCursor )
  3059.  
  3060.      {RECT     rcNewRect;        // resize rect in screen coordinates
  3061.  
  3062.       ptCursor.x += g.ptCursorOffset.x;
  3063.       ptCursor.y += g.ptCursorOffset.y;
  3064.  
  3065.       rcNewRect = g.rcResizeRect;
  3066.       *((LPPOINT) &rcNewRect.right) = ptCursor;
  3067.  
  3068.       if( !EqualRect( &g.rcResizeRect, &rcNewRect ))
  3069.          {DrawTheFrameRect( &g.rcResizeRect, FALSE );
  3070.           g.rcResizeRect = rcNewRect;
  3071.           DrawTheFrameRect( &g.rcResizeRect, FALSE );
  3072.          }
  3073.  
  3074.       return;
  3075.      }
  3076.  
  3077.  
  3078. // Function: FixUpMovieTiling - Sets the dimensions of the movie
  3079. //                              window when tiling
  3080. // --------------------------------------------------------------------
  3081. // Parameters: HWND             hwndMovie      Handle of movie wnd
  3082. //             NPMOVIEDATA      pMovieData     -> movie data struct
  3083. //             LPWINDOWPOS      lpwpWndPos     -> WINDOWPOS struct
  3084. //
  3085. // Returns:    LONG      Always 0L
  3086. // --------------------------------------------------------------------
  3087.    static LONG NEAR FixUpMovieTiling
  3088.         ( HWND hwndMovie, NPMOVIEDATA pMovieData, LPWINDOWPOS lpwpWndPos )
  3089.  
  3090.      {WORD          wMovieWidthMDI;    // Width of tile region
  3091.       WORD          wMovieHeightMDI;   // Height of tile region
  3092.       WORD          wTemp;             // Temp
  3093.       MINMAXINFO    mmiMinMaxInfo;     // MinMax info struct
  3094.  
  3095.  
  3096.       if( pMovieData->bSoundOnly )
  3097.          {SetMinMaxInfo( hwndMovie, pMovieData, &mmiMinMaxInfo );
  3098.           lpwpWndPos->cx =
  3099.                    max( mmiMinMaxInfo.ptMinTrackSize.x,
  3100.                         min( (int) g.wSoundOnlyDefWidth, lpwpWndPos->cx ));
  3101.           lpwpWndPos->cy = mmiMinMaxInfo.ptMaxTrackSize.y;
  3102.  
  3103.           return 0L;
  3104.          }
  3105.  
  3106.       wMovieWidthMDI  = lpwpWndPos->cx - g.wSides;
  3107.       wMovieHeightMDI = lpwpWndPos->cy - g.wTopAndBottom;
  3108.  
  3109.       if( ( wMovieWidthMDI >= pMovieData->idMovieInfo.width ) &&
  3110.                ( wMovieHeightMDI >= pMovieData->idMovieInfo.height ))
  3111.          {lpwpWndPos->cx = pMovieData->idMovieInfo.width + g.wSides;
  3112.           lpwpWndPos->cy = pMovieData->idMovieInfo.height +
  3113.                                                     g.wTopAndBottom;
  3114.          }
  3115.       else   // Try setting height and calc width
  3116.          {wTemp = MulDiv( wMovieHeightMDI,
  3117.                                  pMovieData->idMovieInfo.width,
  3118.                                       pMovieData->idMovieInfo.height );
  3119.               // If it fits, we are done
  3120.           if( wTemp <= wMovieWidthMDI )
  3121.              {lpwpWndPos->cx = wTemp + g.wSides;
  3122.              }
  3123.           else    // Set width and calc height
  3124.              {wTemp = MulDiv( wMovieWidthMDI,
  3125.                                  pMovieData->idMovieInfo.height,
  3126.                                       pMovieData->idMovieInfo.width );
  3127.               lpwpWndPos->cy = wTemp + g.wTopAndBottom;
  3128.              }
  3129.  
  3130.             // Now check for min allowed proportional size
  3131.           AdjustForMinProportionalSize( hwndMovie, pMovieData,
  3132.                           &lpwpWndPos->cx, &lpwpWndPos->cy, FALSE );
  3133.          }
  3134.  
  3135.       return 0L;
  3136.      }
  3137.  
  3138.  
  3139. // Function: SetOptionsDefaults - Set option defaults
  3140. // --------------------------------------------------------------------
  3141. // Parameters: HWND             hwndMovie      Movie hwnd
  3142. //             NPMOVIEDATA      pMovieData     -> movie data struct
  3143. //
  3144. // Returns:    VOID
  3145. // --------------------------------------------------------------------
  3146.    static VOID NEAR SetOptionsDefaults
  3147.                                  ( HWND hwndMovie, NPMOVIEDATA pMovieData )
  3148.  
  3149.      {   // Preset copy struct parameters that do not change
  3150.       pMovieData->qtoleOptions.lStructSize     = sizeof( QTOLE_OPTIONSMOVIE );
  3151.       pMovieData->qtoleOptions.lVersion        = VERSION_1;
  3152.       pMovieData->qtoleOptions.wObjectType     = MOVIE_OBJECT;
  3153.       pMovieData->qtoleOptions.hwndObject      = hwndMovie;
  3154.  
  3155.       pMovieData->qtoleOptions.mMovie          = pMovieData->mMovie;
  3156.       pMovieData->qtoleOptions.bSoundOnlyMovie = pMovieData->bSoundOnly;
  3157.       pMovieData->qtoleOptions.lfxRate         = DEFAULT_RATE;
  3158.  
  3159.       pMovieData->qtoleOptions.sizeNormal.cx   = pMovieData->idMovieInfo.width;
  3160.       pMovieData->qtoleOptions.sizeNormal.cy   = pMovieData->idMovieInfo.height;
  3161.  
  3162.       pMovieData->qtoleOptions.tvMovieDuration =
  3163.                                          GetMovieDuration( pMovieData->mMovie );
  3164.  
  3165.         // This routine queries qtw.ini for defaults
  3166.       PlayerGetDefaultOptions( &pMovieData->qtoleOptions );
  3167.  
  3168.       if( pMovieData->qtoleOptions.bSizeHalf )
  3169.          {pMovieData->qtoleOptions.sizeCurrent.cx =
  3170.                                   pMovieData->qtoleOptions.sizeNormal.cx / 2;
  3171.           pMovieData->qtoleOptions.sizeCurrent.cy =
  3172.                                   pMovieData->qtoleOptions.sizeNormal.cy / 2;
  3173.          }
  3174.       else if( pMovieData->qtoleOptions.bSizeDouble )
  3175.          {pMovieData->qtoleOptions.sizeCurrent.cx =
  3176.                                   pMovieData->qtoleOptions.sizeNormal.cx * 2;
  3177.           pMovieData->qtoleOptions.sizeCurrent.cy =
  3178.                                   pMovieData->qtoleOptions.sizeNormal.cy * 2;
  3179.          }
  3180.       else     // Set to normal size if not half or double
  3181.          {pMovieData->qtoleOptions.sizeCurrent =
  3182.                                   pMovieData->qtoleOptions.sizeNormal;
  3183.          }
  3184.  
  3185.       lstrcpy( pMovieData->qtoleOptions.szCaption, pMovieData->szMovieName );
  3186.       lstrcat( pMovieData->qtoleOptions.szCaption, pMovieData->szMovieExt );
  3187.  
  3188.       return;
  3189.      }
  3190.  
  3191.  
  3192. // Function: UpdateMovieForOptions - Sets movie options according to values
  3193. //                                   set in options dialog
  3194. // --------------------------------------------------------------------
  3195. // Parameters: HWND          hwndMovie;      Movie window handle
  3196. //             NPMOVIEDATA   pMovieData;     Movie data structure
  3197. //             BOOL          bCalledByOLE    TRUE if called by ole callback func.
  3198. //
  3199. // Returns:    None
  3200. // --------------------------------------------------------------------
  3201.    VOID FAR UpdateMovieForOptions
  3202.               ( HWND hwndMovie, NPMOVIEDATA pMovieData, BOOL bCalledByOLE )
  3203.  
  3204.      {TimeRecord   trTime;
  3205.  
  3206.       if( pMovieData->qtoleOptions.bLoop )
  3207.           SendMessage( hwndMovie, WM_COMMAND, PLAYER_MOVIE_LOOP, 0L );
  3208.       else if( pMovieData->qtoleOptions.bLoopPalindrome )
  3209.           SendMessage( hwndMovie, WM_COMMAND, PLAYER_MOVIE_BACKANDFORTH, 0L );
  3210.       else
  3211.           SendMessage( hwndMovie, WM_COMMAND, PLAYER_MOVIE_STOPATEND, 0L );
  3212.  
  3213.       MCDoAction( pMovieData->mcMovieController,
  3214.                   mcActionSetPlaySelection,
  3215.                   (LPVOID) pMovieData->qtoleOptions.bPlaySelectionOnly );
  3216.  
  3217.       if( pMovieData->qtoleOptions.bSizeHalf )
  3218.           SendMessage( hwndMovie, WM_COMMAND, PLAYER_MOVIE_HALFSIZE, 0L );
  3219.       else if( pMovieData->qtoleOptions.bSizeNormal )
  3220.           SendMessage( hwndMovie, WM_COMMAND, PLAYER_MOVIE_NORMALSIZE, 0L );
  3221.       else if( pMovieData->qtoleOptions.bSizeDouble )
  3222.           SendMessage( hwndMovie, WM_COMMAND, PLAYER_MOVIE_DOUBLESIZE, 0L );
  3223.       else if( bCalledByOLE )
  3224.           ResizeMovieAndWindow( hwndMovie, TRUE, pMovieData,
  3225.                              pMovieData->qtoleOptions.sizeCurrent.cx,
  3226.                                  pMovieData->qtoleOptions.sizeCurrent.cy );
  3227.  
  3228.       if( bCalledByOLE )
  3229.          {trTime.value.dwHi = 0L;
  3230.           trTime.value.dwLo = pMovieData->qtoleOptions.tvDisplayFrame;
  3231.           trTime.scale = GetMovieTimeScale( pMovieData->mMovie );
  3232.           trTime.base  = TIMEBASE_DEFAULT;
  3233.  
  3234.           MCDoAction( pMovieData->mcMovieController,
  3235.                                        mcActionGoToTime, (LPVOID) &trTime );
  3236.  
  3237.           MCDoAction( pMovieData->mcMovieController,
  3238.                          mcActionSetSelectionBegin,
  3239.                             (LPVOID) &pMovieData->qtoleOptions.trSelStart );
  3240.           MCDoAction( pMovieData->mcMovieController,
  3241.                          mcActionSetSelectionDuration,
  3242.                             (LPVOID) &pMovieData->qtoleOptions.trSelDuration );
  3243.          }
  3244.  
  3245.       return;
  3246.      }
  3247.  
  3248.  
  3249. // Function: PopulateOptionsStruct - Populates the options structure
  3250. // --------------------------------------------------------------------
  3251. // Parameters: HWND          hwndMovie      HWND of movie
  3252. //             NPMOVIEDATA   pMovieData     Movie data structure
  3253. //
  3254. // Returns:    None
  3255. // --------------------------------------------------------------------
  3256.    static VOID NEAR PopulateOptionsStruct( HWND hwndMovie, NPMOVIEDATA pMovieData )
  3257.  
  3258.      {BOOL           bLoop;                // Looping flag
  3259.       BOOL           bLoopPalindrome;      // Loop palindrome flag
  3260.       RECT           rcMovie;              // Movie rectangle
  3261.       WORD           wMovieWidth;          // Movie width
  3262.       WORD           wMovieHeight;         // Movie height
  3263.       TimeRecord     trMovieTime;          // Movie time.. not used
  3264.  
  3265.  
  3266.         // Update these each time in case they get NULLed somewhere
  3267.       pMovieData->qtoleOptions.hwndObject = hwndMovie;
  3268.       pMovieData->qtoleOptions.mMovie     = pMovieData->mMovie;
  3269.  
  3270.       MCDoAction( pMovieData->mcMovieController,
  3271.                                mcActionGetLooping, (LPVOID) &bLoop );
  3272.       MCDoAction( pMovieData->mcMovieController,
  3273.                      mcActionGetLoopIsPalindrome, (LPVOID) &bLoopPalindrome );
  3274.  
  3275.       pMovieData->qtoleOptions.bLoop           = FALSE;
  3276.       pMovieData->qtoleOptions.bLoopPalindrome = FALSE;
  3277.       if( bLoop )
  3278.          {if( bLoopPalindrome )
  3279.               pMovieData->qtoleOptions.bLoopPalindrome = TRUE;
  3280.           else
  3281.               pMovieData->qtoleOptions.bLoop = TRUE;
  3282.          }
  3283.  
  3284.       MCDoAction( pMovieData->mcMovieController,
  3285.                   mcActionGetPlaySelection,
  3286.                   (LPVOID) &pMovieData->qtoleOptions.bPlaySelectionOnly );
  3287.       if( pMovieData->qtoleOptions.bPlaySelectionOnly )
  3288.          {pMovieData->qtoleOptions.trSelStart = pMovieData->trSelectionStart;
  3289.           pMovieData->qtoleOptions.trSelDuration =
  3290.                                             pMovieData->trSelectionDuration;
  3291.          }
  3292.       else
  3293.          {memset( &pMovieData->qtoleOptions.trSelStart,
  3294.                                                  0, sizeof( TimeRecord ));
  3295.           memset( &pMovieData->qtoleOptions.trSelDuration,
  3296.                                                  0, sizeof( TimeRecord ));
  3297.          }
  3298.  
  3299.       GetMovieBox( pMovieData->mMovie, &rcMovie );
  3300.       wMovieWidth  = rcMovie.right  - rcMovie.left;
  3301.       wMovieHeight = rcMovie.bottom - rcMovie.top;
  3302.  
  3303.       pMovieData->qtoleOptions.sizeCurrent.cx = wMovieWidth;
  3304.       pMovieData->qtoleOptions.sizeCurrent.cy = wMovieHeight;
  3305.  
  3306.       if( !pMovieData->qtoleOptions.bSoundOnlyMovie )
  3307.          {if( !pMovieData->qtoleOptions.bCopyCurrentFrame )
  3308.              {pMovieData->qtoleOptions.tvDisplayFrame =
  3309.                                   GetMoviePosterTime( pMovieData->mMovie );
  3310.              }
  3311.           else
  3312.              {pMovieData->qtoleOptions.tvDisplayFrame =
  3313.                            GetMovieTime( pMovieData->mMovie, &trMovieTime );
  3314.              }
  3315.          }
  3316.       else
  3317.          {pMovieData->qtoleOptions.tvDisplayFrame = 0;
  3318.          }
  3319.  
  3320.       return;
  3321.      }
  3322.  
  3323.  
  3324. //  This function is a query function called by other modules
  3325.  
  3326. // Function: PlayerQueryActiveMovieName - Query name of active movie
  3327. // --------------------------------------------------------------------
  3328. // Parameters: LPSTR      lpBuffer       string buffer
  3329. //
  3330. // Returns:    LPSTR      lpBuffer       Name of active movie
  3331. // --------------------------------------------------------------------
  3332.    LPSTR FAR PlayerQueryActiveMovieName( LPSTR lpBuffer )
  3333.  
  3334.      {HWND          hwndMovie;    // Handle to active window
  3335.       NPMOVIEDATA   pMovieData;   // ->movie data struct
  3336.  
  3337.       hwndMovie = (HWND) SendMessage
  3338.                     ( PlayerQueryClientWindow(), WM_MDIGETACTIVE, 0, 0L );
  3339.       *lpBuffer = 0;
  3340.       if( pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 ))
  3341.           lstrcpy( lpBuffer, pMovieData->szMovieName );
  3342.  
  3343.       return lpBuffer;
  3344.      }
  3345.